多行到一行Oracle SQL

时间:2015-10-08 12:21:30

标签: sql oracle oracle11g

我有下表

P_ID, PROGR, DATA  
 1  ,  1   , 'DATO A'
 1  ,  2   , 'DATO B' 
 1  ,  3   , 'DATO C' 
 2  ,  1   , 'DATO D' 
 2  ,  2   , 'DATO E' 
 3  ,  1   , 'DATO G' 

我希望得到这个结果

P_ID,   DATA  ,  DATA_1 ,  DATA_2
 1  , 'DATO A', 'DATO B', 'DATO C'
 2  , 'DATO D', 'DATO E',   NULL   
 3  , 'DATO G',   NULL  ,   NULL

这可以使用同一个表的左连接来完成,类似这样(不是确切的结果,但作为示例)

select * from
(select * from MYTABLE where PROGR = 1) a
left join 
(select * from MYTABLE where PROGR = 2) b
on a.P_ID = b.P_ID
left join
(select * from MYTABLE where PROGR = 3) c
on a.P_ID = c.P_ID;

问题是这个查询是固定的,如果某些P_ID得到PROGR = 4,需要重写。我认为我需要制作一个程序,但我一直在尝试没有成功。

提前致谢。

2 个答案:

答案 0 :(得分:3)

您可以使用条件聚合:

select t.pid,
       max(case when t.progr = 1 then t.data end) as data_1,
       max(case when t.progr = 2 then t.data end) as data_2,
       max(case when t.progr = 3 then t.data end) as data_3
from mytable t
group by t.pid;

为了处理可变数量的列,我可以想到三个解决方案:

  1. 放入足够的列来处理您的数据(最合理的一些)。
  2. 在PL / SQL中使用动态SQL(execute immediate)。
  3. 或者,将它们组合成一列。
  4. 这是最后一种方法:

    select t.pid, listagg(t.data, ', ') within group (order by t.progr)
    from mytable t
    group by t.pid;
    

答案 1 :(得分:1)

使用以下查询。

select p_id,max(data_1) as data_1,max(data_2)as data_2,max(data_3) as data_3
    from
    (select P_ID,
    case when progr=1 then 
    data
    end data_1,
    case when progr=2 then 
    data
    end data_2,
    case when progr=3 then 
    data
    end data_3
    from thursday_check)
    group by p_id