oraclesql中的两列数据透视

oraclesql中的两列数据透视,oracle,Oracle,我对Oracle中的数据透视有一个问题。这是我的数据 ID, TaskName, Type, Date 44400 M0 A 1/1/2015 44400 M1 A 1/3/2015 44400 M2 A 1/4/2015 44400 M1 CF 2/1/2105 44400 DG1 CF 2/2/2015 44400 M0 POR 2/11/2015 45000 M0 A 2/1/2015 45000 M1 A 2/3/2015 45000 M2 A 2/4/2015 45000 M1 CF

我对Oracle中的数据透视有一个问题。这是我的数据

ID, TaskName, Type, Date
44400 M0 A 1/1/2015
44400 M1 A 1/3/2015
44400 M2 A 1/4/2015
44400 M1 CF 2/1/2105
44400 DG1 CF 2/2/2015
44400 M0 POR 2/11/2015
45000 M0 A 2/1/2015
45000 M1 A 2/3/2015
45000 M2 A 2/4/2015
45000 M1 CF 3/1/2105
45000 DG1 CF 3/2/2015
45000 M0 POR 3/11/2015
我想以上面的数据为轴心,动态地需要下面的表单

现在,我需要如下数据

ID M0_A M1_A M2_A M1_CF DG1_CF M0_POR
44400 1/1/2015 1/3/2015 1/4/2015 2/1/2015 2/2/2015 2/11/2015
45000 2/1/2015 2/3/2015 2/4/2015 3/1/2015 3/2/2015 3/11/2015

我真的很感谢你的帮助。提前感谢。

有关列
tname中定义的值对数量,请键入以下查询(注意,我更改了示例中的列名,
因为您在这里使用了Oracle关键字,所以我将表命名为
tasks
,所以您必须将此数据更改为实际的列名和表名(代码中的任意位置):

对于动态数量的可能性,您需要一些“创建”此查询的过程。在这里,我使用了
视图
。 复制程序代码并编译它。当表中的数据发生更改时,首先必须运行该过程,然后只需从该过程创建的视图中进行选择。 为了正确运行您的模式,需要授予创建视图的特权

execute create_tasks_view;
select * from v_tasks;

anonymous block completed
   ID DG1_CF     M0_A       M0_POR     M1_A       M1_CF      M2_A     
----- ---------- ---------- ---------- ---------- ---------- ----------
45000 2015-03-02 2015-02-01 2015-03-11 2015-02-03 2015-03-01 2015-02-04 
44400 2015-02-02 2015-01-01 2015-02-11 2015-01-03 2015-02-01 2015-01-04
当然,您可以根据需要更改行和列的顺序,方法是在过程代码中添加或修改
order by
部分:

create or replace procedure create_tasks_view as 
  v_sql varchar2(32767) := '';
begin
  for v in (select distinct tname, ttype from tasks order by tname, ttype) 
  loop
    v_sql := v_sql || '(''' || v.tname || ''',''' || v.ttype || ''') '
      ||v.tname||'_'||v.ttype||',';
  end loop;
  v_sql := 'create or replace view v_tasks as '
    ||'select * from tasks pivot (max(tdate) for (tname, ttype) in ('
    ||rtrim(v_sql, ', ')||'))'; 
  execute immediate v_sql;
end create_tasks_view;

我相信在我在评论中给你们的链接中也有更普遍的解决方案。它看起来很有希望,只要仔细阅读底部的参考资料部分,并按照说明的步骤进行操作即可。我没有亲自检查此方法,但可能这比我的“过程视图”解决方案更适合您。

对于已知数量的值,您可以在(('M0','A'),('M1','A'))中定义pivot子句:
select*fromtpivot(max(date)For(taskname,type))
。对于全动态解决方案,请阅读本文。感谢您的回复,但我希望获得全动态解决方案,但我不理解您发送的文章链接。如果可以的话,你能在这里向我询问一下吗?谢谢
create or replace procedure create_tasks_view as 
  v_sql varchar2(32767) := '';
begin
  for v in (select distinct tname, ttype from tasks order by tname, ttype) 
  loop
    v_sql := v_sql || '(''' || v.tname || ''',''' || v.ttype || ''') '
      ||v.tname||'_'||v.ttype||',';
  end loop;
  v_sql := 'create or replace view v_tasks as '
    ||'select * from tasks pivot (max(tdate) for (tname, ttype) in ('
    ||rtrim(v_sql, ', ')||'))'; 
  execute immediate v_sql;
end create_tasks_view;