Oracle SQL使用动态列名进行转置

时间:2012-06-06 19:53:58

标签: sql oracle pivot

我有一个简单的问题需要快速解决。你能借我帮忙吗?

问题是如下:我有两个表,一个定义表和一个历史表。

create table revenue history(operation_date date, revenue_id number, total_revenue number); 
create table revenue_definition(revenue_id number, revenue_name varchar2(100));

insert into revenue_definition values(1,'Car');
insert into revenue_definition values(2,'Minivan');
insert into revenue_definition values(3,'Bus');

insert into revenue history values(sysdate-2,1,100);
insert into revenue history values(sysdate-2,2,150);
insert into revenue history values(sysdate-2,3,100);

insert into revenue history values(sysdate-1,1,200);
insert into revenue history values(sysdate-1,2,150);
insert into revenue history values(sysdate-1,3,200);

insert into revenue history values(sysdate,1,100);
insert into revenue history values(sysdate,2,150);
insert into revenue history values(sysdate,3,100);

现在我需要做的是显示这样的报告;

  

operation_date汽车小型货车巴士
  sysdate 100 150 100
  sysdate-1 200 150 200
  sysdate-2 100 150 100

我知道我可以通过使用解码或11g枢轴来完成此操作。但对于那些我需要事先了解收入类型(汽车,小型货车等)的人,每次定义时我都需要更新我的代码。如果可能的话,我想避免这种情况。

欢迎任何建议,

感谢。

3 个答案:

答案 0 :(得分:2)

听起来像是动态sql的候选者。每次运行查询时,您都需要将sql语句实际构建为字符串。您可以通过从定义表中执行select,循环遍历定义并将它们添加到sql语句来构建列名称字符串,然后:

execute immediate 'sql statement'

我知道没有其他方法可以动态更改查询运行时显示的列。

答案 1 :(得分:2)

此代码在Oracle 11g(11.2.0)数据库的SQL * Plus中运行。

column dummy noprint
column "Header" format a14
column "Data"   format a40
SELECT 0 DUMMY
      ,'Operation Date' "Header"
      ,LISTAGG(lpad(' ', 9 - length(d.revenue_name) ,' ') || d.revenue_name ) WITHIN GROUP (ORDER BY d.revenue_id) "Data"
FROM  revenue_definition d
UNION
SELECT 1
      ,to_Char(h.operation_date,'DD-MON-YYYY')
      ,LISTAGG(lpad(' ',9 - length(h.total_revenue),' ') ||h.total_revenue) WITHIN GROUP (Order by d.revenue_id)
FROM revenue_definition d
    ,revenue_history    h
where h.revenue_id = d.revenue_id
group by h.operation_date
ORDER by 1, 2;

并生成此输出:

Header           Data
-------------- ----------------------------------------
Operation Date       Car  Minivan      Bus
15-OCT-2012          100      150      100
16-OCT-2012          200      150      200
17-OCT-2012          100      150      100

答案 2 :(得分:0)

您可以将定义内容作为单行输出 - 将其连接回定义和历史记录,应返回您想要的内容并调整为定义中的数据更改。

一个例子: http://docs.oracle.com/cd/E18283_01/appdev.112/e17126/tuning.htm#BABIEICA