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并遍历。谢谢你的回答