SQL查询以透视下表中的数据

时间:2019-02-24 17:25:39

标签: mysql sql oracle sqlite relational-database

我的出勤目录如下,

Catlog Table

如上图所示, 全班有4名学生,他们的卷号分别为1,2,3,4。 相应的授课时间,三名名为PNT,SGP和DAP的老师参加了同一堂课。 上表显示了每个学生相对于每个老师的缺勤情况。

我想生成如下输出,

enter image description here

此表说明在相应老师的授课下每个学生的缺勤情况。

如何从给定的表中获得这样的结果?


DDL和示例数据:

create table mytable ( TeacherID varchar(3), RollNo number, Total_Absency number);
insert into mytable values('PNT', 1, 0);
insert into mytable values('PNT', 2, 4);
insert into mytable values('PNT', 3, 0);
insert into mytable values('PNT', 4, 1);
insert into mytable values('SGP', 1, 2);
insert into mytable values('SGP', 2, 1);
insert into mytable values('SGP', 3, 1);
insert into mytable values('SGP', 4, 1);
insert into mytable values('DAP', 1, 1);
insert into mytable values('DAP', 2, 1);
insert into mytable values('DAP', 3, 1);
insert into mytable values('DAP', 4, 0);

1 个答案:

答案 0 :(得分:2)

对于Oracle,使用PIVOT子句:

SELECT * FROM
(
  SELECT TeacherID, RollNo, Total_Absency FROM mytable
)
PIVOT 
(
  MAX(Total_Absency)
  FOR TeacherID
  IN ( 'PNT', 'SGP', 'DAP' )
)
ORDER BY RollNo

Demo on DB Fiddle

 
ROLLNO | 'PNT' | 'SGP' | 'DAP'
-----: | ----: | ----: | ----:
     1 |     0 |     2 |     1
     2 |     4 |     1 |     1
     3 |     0 |     1 |     1
     4 |     1 |     1 |     0

对于其他RDBMS,一般的解决方案是使用条件聚合:

SELECT
    RollNo,
    MAX(CASE WHEN TeacherID = 'PNT' THEN Total_Absency END) AS PNT,
    MAX(CASE WHEN TeacherID = 'SGP' THEN Total_Absency END) AS SGP,
    MAX(CASE WHEN TeacherID = 'DAP' THEN Total_Absency END) AS DAP
FROM mytable
GROUP BY RollNo
ORDER BY RollNo