SQL 识别非小计行,你已经知道如何使用 GROUP BY
子句的 CUBE
扩展语法生成报表,并且你需要知道如何区分哪些行是由普通的 GROUP BY
子句产生的,哪些行是由 CUBE
或 ROLLUP
产生的。
SQL 识别非小计行 问题描述
你已经知道如何使用 GROUP BY
子句的 CUBE
扩展语法生成报表,并且你需要知道如何区分哪些行是由普通的 GROUP BY
子句产生的,哪些行是由 CUBE
或 ROLLUP
产生的。
下面给出了一组利用 GROUP BY
的 CUBE
扩展语法生成的查询结果集,它是 EMP
表中员工工资的一个分类汇总结果。
以上报表展示了按照 DEPTNO
和 JOB
分组计算出来的(每个 DEPTNO
对应的每一种 JOB
的)工资合计值,按照 DEPTNO
分组计算出来的工资合计值,按照 JOB
分组计算出来的工资合计值,以及最后的总计(EMP
表的工资合计值)。你希望能清楚地识别上述各种聚合运算的维度,并标记出每一个聚合运算结果分别属于哪一类。(也就是说,给定的 SAL
值代表的是按照 DEPTNO
分组计算的结果,还是按照 JOB
分组计算的结果,或者是总计?)你希望返回如下所示的结果集。
SQL 识别非小计行 解决方案
使用 GROUPING
函数判断哪些值是 CUBE
或 ROLLUP
的小计结果,即超级聚合(supera ggregate)值。下面是 DB2 和 Oracle 的示例代码。
相较于 DB2 和 Oracle 解决方案,SQL Server 解决方案唯一的不同之处在于 CUBE/ROLLUP
子句的语法。
本实例的重点在于展示如何使用 CUBE
和 GROUPING
处理小计计算。在写作本书时,PostgreSQL 和 MySQL 尚不支持 CUBE
或 GROUPING
。
SQL 识别非小计行 扩展知识
如果 DEPTNO_SUBTOTALS
等于 0,并且 JOB_SUBTOTALS
等于 1(此时 JOB
是 Null
),那么 SAL
值就是 CUBE
查询生成的、按照 DEPTNO
分组的小计结果。如果 JOB_SUBTOTALS
等于 0,并且 DEPTNO_SUBTOTALS
等于 1(此时 DEPTNO
是 Null
),那么 SAL
值就是 CUBE
查询生成的、按照 JOB
分组的小计结果。如果 JOB_SUBTOTALS
和 DEPTNO_SUBTOTALS
都等于 1,那么 SAL
值就是 CUBE
查询生成的工资总计。DEPTNO_SUBTOTALS
和 JOB_SUBTOTALS
都等于 0 的行则是通常的聚合运算结果(每个 DEPTNO/JOB
组合对应的 SAL
合计)。