Oracle 像pivot一样将行转换为列

Oracle 像pivot一样将行转换为列,oracle,plsql,Oracle,Plsql,我的数据如下: formid formownerid approverid 1 100 102 1 100 103 1 100 104 2 200 107 2 200 103 2 200 109 2 200 105 3 400 201 3 400

我的数据如下:

formid  formownerid approverid
1       100         102
1       100         103
1       100         104
2       200         107
2       200         103
2       200         109
2       200         105
3       400         201
3       400         210
我想将其转换为:

formid  formownerid approverid  approverid  approverid  approverid
1       100         102         103         104         NULL
2       200         107         103         109         105
3       400         201         202         NULL        NULL
无论我在哪里看到pivot/unpivot,但它看起来不相关,因为我们不需要聚合。

一种可能的方法:

SELECT FROMID, FROMOWNERID, APPROVERID, NULL APPROVERID, NULL APPROVERID, NULL APPROVERID
FROM   yourtable
WHERE  FROMID = 100
AND    APPROVERID =  102
UNION ALL
SELECT FROMID, FROMOWNERID, NULL APPROVERID, APPROVERID APPROVERID, NULL APPROVERID, NULL APPROVERID
FROM   yourtable
WHERE  FROMID = 100
AND    APPROVERID =  103
UNION ALL
SELECT FROMID, FROMOWNERID, NULL APPROVERID, NULL APPROVERID, APPROVERID APPROVERID, NULL APPROVERID
FROM   yourtable
WHERE  FROMID = 100
AND    APPROVERID =  104
----
-------
And So On

聚合是轴心的必要部分,但在这里应用很简单;您不需要
sum
,但是
max
聚合可以正常工作:

select *
from (
  select t.*,
    row_number() over (partition by formid, formownerid
      order by approverid) as rn
  from t42 t
)
pivot (max(approverid) as approverid for (rn) in (1, 2, 3, 4));

    FORMID FORMOWNERID 1_APPROVERID 2_APPROVERID 3_APPROVERID 4_APPROVERID
---------- ----------- ------------ ------------ ------------ ------------
         1         100          102          103          104              
         2         200          103          105          107          109 
         3         400          201          210                           
或者,可以显式指定列名前缀,使其成为有效标识符:

pivot (max(approverid) as approverid
  for (rn) in (1 as a, 2 as b, 3 as c, 4 as d));
内部查询向表results添加一个伪列
rn
,为您提供一个固定的值作为透视依据,因为实际的审批人ID不会事先知道

手动方法可能会使这一点更加清楚:

select formid, formownerid,
  max(case when rn = 1 then approverid end) as approverid_1,
  max(case when rn = 2 then approverid end) as approverid_2,
  max(case when rn = 3 then approverid end) as approverid_3,
  max(case when rn = 4 then approverid end) as approverid_4
from (
  select t.*,
    row_number() over (partition by formid, formownerid
      order by approverid) as rn
  from t42 t
)
group by formid, formownerid
order by formid, formownerid;

    FORMID FORMOWNERID APPROVERID_1 APPROVERID_2 APPROVERID_3 APPROVERID_4
---------- ----------- ------------ ------------ ------------ ------------
         1         100          102          103          104              
         2         200          103          105          107          109 
         3         400          201          210                           
内部查询是相同的。
case
语句生成如上所述的每一列,但如果没有
max
和分组,您将得到多行,其中包含大量额外的空格:

select formid, formownerid,
  case when rn = 1 then approverid end as approverid_1,
  case when rn = 2 then approverid end as approverid_2,
  case when rn = 3 then approverid end as approverid_3,
  case when rn = 4 then approverid end as approverid_4
from (
  select t.*,
    row_number() over (partition by formid, formownerid
      order by approverid) as rn
  from t42 t
);

    FORMID FORMOWNERID APPROVERID_1 APPROVERID_2 APPROVERID_3 APPROVERID_4
---------- ----------- ------------ ------------ ------------ ------------
         1         100          102                                        
         1         100                       103                           
         1         100                                    104              
         2         200          103                                        
         2         200                       105                           
         2         200                                    107              
         2         200                                                 109 
         3         400          201                                        
         3         400                       210                           
请注意,对于每个
formid
/
formownerid
组合,在(最多)一列中只有一个值,但它们显示在不同的行中。
max
抑制这些多行;pivot版本在引擎盖下也有类似的功能


显示中间步骤的手动方法和pivot版本。

我们谈论的是大数据。我们不能写ids'I suggest PLSQL,Pipelined Functions Hanks,我猜它可以工作,但是我们在oracle对象透视中遇到了一些问题,因为状态是紧急的,我们艰难地完成了它,并进行了迭代。并且还附加了字符串(在approver列上)。谢谢。@Doruk-pivot直到11g才可用,所以如果您使用的是早期版本,那么它将是“object”。max/case版本在早期版本上也可以使用。因为状态是紧急状态,所以我们编写了一个func并遍历。谢谢你的回答