假如现在我们有这样一张表,命名为TB_STUDENT_SCORE
表中内容为:
可能会用到pivot的常见情况是:需要生成交叉表格报表以汇总数据。例如,假设需要在 TB_STUDENT_SCORE表中
中查询 学生姓名,各科成绩,总分,平均分,名称以生成报表
。
如下图所示:
以下是带批注的 PIVOT 语法。
SELECT <非透视的列>,
[第一个透视的列] AS <列名称>,
[第二个透视的列] AS <列名称>,
...
[最后一个透视的列] AS <列名称>,
FROM
(<生成数据的 SELECT 查询>)
AS <源查询的别名>
PIVOT
(
<聚合函数>(<要聚合的列>)
FOR
[<包含要成为列标题的值的列>]
IN ( [第一个透视的列], [第二个透视的列],
... [最后一个透视的列])
) AS <透视表的别名>
<可选的 ORDER BY 子句>;
pivot_column 和 value_column 是 PIVOT 运算符使用的分组列。PIVOT 遵循以下过程获得输出结果集:
pivot_column = CONVERT(<data type of pivot_column>, 'output_column')
在上述列子中,我们可以用以下SQL完成其功能
1.首先使用PIVOT进行行列转换
SELECT STUDENT_NAME, CET.[A],CET.[B],CET.[C],CET.[D] FROM TB_STUDENT_SCORE PIVOT (AVG(STUDENT_SCORE) FOR STUDENT_SUBJECT IN([A],[B],[C],[D])) AS CET
2.使用开窗函数统计学生成绩
SELECT T1.*, AVG(T2.STUDENT_SCORE) OVER (PARTITION BY T2.STUDENT_NAME) AS '平均成绩' ,SUM(T2.STUDENT_SCORE) OVER (PARTITION BY T2.STUDENT_NAME) AS '总分' FROM ( SELECT STUDENT_NAME, CET.[A],CET.[B],CET.[C],CET.[D] FROM TB_STUDENT_SCORE PIVOT (AVG(STUDENT_SCORE) FOR STUDENT_SUBJECT IN([A],[B],[C],[D])) AS CET ) T1 LEFT JOIN TB_STUDENT_SCORE T2 ON T1.STUDENT_NAME=T2.STUDENT_NAME
3.去除重复行
SELECT DISTINCT * FROM( SELECT T1.*, AVG(T2.STUDENT_SCORE) OVER (PARTITION BY T2.STUDENT_NAME) AS '平均成绩' ,SUM(T2.STUDENT_SCORE) OVER (PARTITION BY T2.STUDENT_NAME) AS '总分' FROM ( SELECT STUDENT_NAME, CET.[A],CET.[B],CET.[C],CET.[D] FROM TB_STUDENT_SCORE PIVOT (AVG(STUDENT_SCORE) FOR STUDENT_SUBJECT IN([A],[B],[C],[D])) AS CET ) T1 LEFT JOIN TB_STUDENT_SCORE T2 ON T1.STUDENT_NAME=T2.STUDENT_NAME ) T3
最终,得到