问题描述
我正在尝试创建一个查询,以使用PIVOT函数将行转置为列。我有一个这种形式的表(这只是局部视图,该表包含30多个列)。
ID SUBJECT GRADE
000442 WRI001 C-
000442 PHY104 C
000442 MTH111 B
000442 MTH111 W
000442 MTH111 W
000442 PHY104 W
预期结果:
ID 'WRI001' 'MTH111' 'PHY104'
000442 C- B,W,W C,W
使用的查询:
select * from (
select ID,SUBJECT,GRADE
from SECOND_YEAR_COMP
)
pivot
(
MAX(GRADE)
for SUBJECT in
('MTH111','WRI001','PHY104')
);
ID 'WRI001' 'MTH111' 'PHY104'
000442 C- W W
我知道由于MAX(GRADE),我每个科目都获得单年级。有什么方法可以获取该学科的所有成绩(如我上面预期的结果所示)。
解决方法
您可以使用listagg()
和条件聚合:
select id,listagg(case when subject = 'WRI001' then grade end) WRI001,listagg(case when subject = 'PHY104' then grade end) PHY104
from second_year_comp
group by id
您可以使用within group
子句控制成绩在并置字符串中的显示顺序。假设您要按年级订购,然后:
select id,listagg(case when subject = 'WRI001' then grade end) within group(order by grade) WRI001,listagg(case when subject = 'PHY104' then grade end) within group(order by grade) PHY104
from second_year_comp
group by id
,
您已经快完成了-唯一的缺憾是-您应使用{中的完整语法将MAX
聚合函数替换为LISTAGG
函数{1}}子句。
此外,我还调整了枢轴列名称以获得好名称(不带撇号)。
请参见以下示例:
PIVOT
预期结果
select * from (
select ID,SUBJECT,GRADE
from tab
)
pivot
(
LISTAGG(GRADE,',') within group (order by GRADE)
for SUBJECT in
('MTH111' as MTH111,'WRI001' as WRI001,'PHY104' as PHY104)
)
,
您可以使用listagg()
进行字符串聚合,然后应用数据透视
With cte as
(
SELECT ID,LISTAGG(GRADE,') WITHIN GROUP (ORDER BY grade) AS grade
FROM tablename
GROUP BY id,SUBJECT
)
select * from (
select ID,GRADE from cte)
pivot
(
MAX(GRADE)
for SUBJECT in ('MTH111','WRI001','PHY104')
);