最近两天在忙着买房子的事情,耽误了两天。今天我们来说说分组集合的相关内容。
在我们制作报表的时候常常需要分组聚合、多组聚合和总合。如果通过另外的T-SQL语句来聚合难免性能太差。如果通过报表工具的聚合功能虽说比使用额外的T-SQL语句性能上要好很多,不过不够干脆,还是需要先生成整个结果集然后再聚合,而且最最重要的时很多情况下报表的聚合功能可能没办法达到我们需要的效果。GROUPING SETS, CUBE, ROLLUP, GROUPING, GROUPING_ID这几个聚合函数的作用就是在原始语句的基础上完成很多像财务报表需要的聚合功能。
GROUPING SETS
GROUPING SETS相当于把多个GROUP BY语句通过UNION ALL
WITH T AS(
SELECT 'A' A, 'A' B UNION ALL
SELECT 'A' A, 'B' B UNION ALL
SELECT 'A' A, 'C' B UNION ALL
SELECT 'B' A, 'A' B UNION ALL
SELECT 'B' A, 'B' B UNION ALL
SELECT 'B' A, 'C' B UNION ALL
SELECT 'C' A, 'A' B UNION ALL
SELECT 'C' A, 'B' B UNION ALL
SELECT 'C' A, 'C' B)
SELECT A, B,
COUNT(A) AS CNT,
GROUPING_ID(A,B)FROM T
GROUP BY GROUPING SETS(A, B, ());
结果如下:
通常GROUPING SETS会配合GROUPING_ID或GROUPING函数来完成列的输出,比如聚合列的标签内容。
GROUPING_ID (a, b, c) = GROUPING(a) + GROUPING(b) + GROUPING(c)
GROUPING 用于区分标准空值和由 ROLLUP、CUBE 或 GROUPING SETS 返回的空值。 作为 ROLLUP、CUBE 或 GROUPING SETS 操作结果返回的 NULL 是 NULL 的特殊应用。 它在结果集内作为列的占位符,表示全体。其实意思就是如果列输出为NULL说明是聚合列,不为空就不是聚合列。一开始很难理解。
在只有一列作为GROUP BY CUBE/ROLLUP的列的情况下,两个函数是一样的效果。
CUBE和ROLLUP的区别就是CUBE比ROLLUP多输出多列的情况下,CUBE比ROLLUP多做的事情就是针对后面列的单独聚合行输出。
WITH T AS (
SELECT 'A' A, 'A' B UNION ALL
SELECT 'A' A, 'B' B UNION ALL
SELECT 'A' A, 'C' B UNION ALL
SELECT 'B' A, 'A' B UNION ALL
SELECT 'B' A, 'B' B UNION ALL
SELECT 'B' A, 'C' B UNION ALL
SELECT 'C' A, 'A' B UNION ALL
SELECT 'C' A, 'B' B UNION ALL
SELECT 'C' A, 'C' B)
SELECT A, B,
COUNT(A) AS CNT,
GROUPING_ID(A,B)
FROM T
GROUP BY A,B
WITH CUBE
;WITH T AS (
SELECT 'A' A, 'A' B UNION ALL
SELECT 'A' A, 'B' B UNION ALL
SELECT 'A' A, 'C' B UNION ALL
SELECT 'B' A, 'A' B UNION ALL
SELECT 'B' A, 'B' B UNION ALL
SELECT 'B' A, 'C' B UNION ALL
SELECT 'C' A, 'A' B UNION ALL
SELECT 'C' A, 'B' B UNION ALL
SELECT 'C' A, 'C' B)
SELECT A, B,
COUNT(A) AS CNT,
GROUPING_ID(A,B)
FROM T
GROUP BY A,B
WITH ROLLUP
CUBE 查询结果如下:
ROLLUP查询结果如下: