使用PIVOT函数Oracle行到列

问题描述

我正在尝试创建一个查询,以使用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')
);