SQL 使用SQL Server的PIVOT操作符创建交叉报表,你想创建一个交叉报表,以实现把行形式的结果集转换为列形式。你已经掌握了传统的做法,但这次希望尝试一些不同的技巧。尤其是你希望不使用 CASE
表达式或连接操作就能返回如下所示的结果集。
SQL 使用SQL Server的PIVOT操作符创建交叉报表 问题描述
你想创建一个交叉报表,以实现把行形式的结果集转换为列形式。你已经掌握了传统的做法,但这次希望尝试一些不同的技巧。尤其是你希望不使用 CASE
表达式或连接操作就能返回如下所示的结果集。
SQL 使用SQL Server的PIVOT操作符创建交叉报表 解决方案
使用 PIVOT
操作符生成要求的结果集,而不使用 CASE
表达式或额外的连接操作。
SQL 使用SQL Server的PIVOT操作符创建交叉报表 扩展知识
最初看到 PIVOT
操作符可能会觉得陌生,其实在上述解决方案中,它执行的操作在技术上等价于我们所熟知的形式变换查询,如下所示。
在对 PIVOT
操作有了基本的了解后,现在我们把它拆解开来,看看它究竟做了些什么。上述解决方案中的第 5 行展示了内嵌视图 DRIVER
。
我选择使用别名 driver
,是因为该内嵌视图[即“表表达式”(table expression)]中的数据会直接流入 PIVOT
操作。PIVOT
操作符通过评估第 8 行的 FOR
列表中的项目把行转换为列,如下所示。
执行过程大致如下。
(1) 如果 DEPTNO
等于 10,就针对相关的行执行预先定义好的聚合操作(COUNT(DRIVER.EMPNO)
)。
(2) 针对 DEPTNO
等于 20、30 和 40 的行重复同样的操作。
第 8 行方括号里的项目不仅能够为聚合操作提供值,同时,这些项目也变成了结果集里的列名(不带方括号)。上述解决方案的 SELECT
子句也引用了 FOR
列表里的那些项目,并为它们分别指定了别名。如果不为 FOR
列表里的项目指定别名,则那些项目就会变成列名,但是会去掉方括号。
还有一个非常有趣之处,由于 DRIVER
只是一个普通的内嵌视图,因此可以使用更复杂的 SQL。假设我们希望修改结果集,把实际的部门名称作为结果集的列名。下面列出了 DEPT
表的数据。
我们希望借助 PIVOT
返回如下所示的结果集。
内嵌视图 DRIVER
事实上能够接受任何有效的表表达式,因此可以先把 EMP
表和 DEPT
表连接起来,然后使用 PIVOT
逐一评估其查询结果。下面的查询将返回上述要求的结果集。
如上所述,PIVOT
提供了一种有趣的转换结果集的办法。如果你以前习惯使用传统的转换方法,现在不妨将其作为另一种选择放入你的工具箱。