ROLLUP 聚合
作为 GROUP BY 子句的扩展来自动执行小计聚合。 ROLLUP
在单个 SQL 查询内的不同级别跨多个维度执行聚合。
您可以将 ROLLUP
子句与三个分组函数一起使用:
语法
ROLLUP grouping-expression[,...]
参数
- group‑expression
- 以下两项中的一个或两个:
-
一个包含常数和
FROM
指定的表中的列引用且不是聚合或分组函数的表达式。例如:column1, (column2+1), column3+column4
-
一个多级表达式,是以下几项之一:
-
ROLLUP
-
CUBE
-
GROUPING SETS
-
-
限制
GROUP BY ROLLUP
不会对结果排序。要对数据进行排序,ORDER BY
子句必须跟在 GROUP BY
子句之后。
聚合级别
如果 n 为分组列的数量,则 ROLLUP
将生成 n+1 个小计和总计级别。由于 ROLLUP
将删除每一步中最右侧的列,所以请仔细指定列顺序。
假设 ROLLUP(A, B, C)
创建 4 个组:
-
(A, B, C)
-
(A, B)
-
(A)
-
()
由于 ROLLUP
将删除每一步中最右侧的列,所以没有 (A, C)
和 (B, C)
组。
如果将 2 个或更多的列括在圆括号内,GROUP BY
会将其视为单一实体。例如:
-
ROLLUP(A, B, C)
将创建 4 个组:(A, B, C) (A, B) (A) ()
-
ROLLUP((A, B), C)
会将(A, B)
视为单一实体并创建 3 个组:(A, B, C) (A, B) ()
示例:聚合完整数据集
以下示例显示了如何使用 GROUP BY
子句确定几年内家庭用电和书籍的开支。SUM
聚合函数计算每年在各类别上的总开销。
假设您有一个表,其中包含关于家庭书籍和用电开支的信息:
=> SELECT * FROM expenses ORDER BY Category, Year;
Year | Category | Amount
------+-------------+--------
2005 | Books | 39.98
2007 | Books | 29.99
2008 | Books | 29.99
2005 | Electricity | 109.99
2006 | Electricity | 109.99
2007 | Electricity | 229.98
对于 expenses
表,ROLLUP
计算 2005–2007 年之间各类别的小计:
-
书籍:$99.96
-
用电:$449.96
-
总计:$549.92。
使用 ORDER BY
子句对结果排序:
=> SELECT Category, Year, SUM(Amount) FROM expenses
GROUP BY ROLLUP(Category, Year) ORDER BY 1,2, GROUPING_ID();
Category | Year | SUM
-------------+------+--------
Books | 2005 | 39.98
Books | 2007 | 29.99
Books | 2008 | 29.99
Books | | 99.96
Electricity | 2005 | 109.99
Electricity | 2006 | 109.99
Electricity | 2007 | 229.98
Electricity | | 449.96
| | 549.92
示例:将 ROLLUP 与 HAVING 子句一起使用
此示例说明如何将 ROLLUP
与 HAVING 子句一起使用,以限制 GROUP BY
结果。以下查询只生成 ROLLUP
类别,其中 year
根据 GROUPING
函数中的表达式得出小计:
=> SELECT Category, Year, SUM(Amount) FROM expenses
GROUP BY ROLLUP(Category,Year) HAVING GROUPING(Year)=1
ORDER BY 1, 2, GROUPING_ID();
Category | Year | SUM
-------------+------+--------
Books | | 99.96
Electricity | | 449.96
| | 549.92
下一个示例对 (Category
, Year
) 而非完整结果进行汇总。GROUPING_ID
函数指定聚合 3 个以下的级别:
=> SELECT Category, Year, SUM(Amount) FROM expenses
GROUP BY ROLLUP(Category,Year) HAVING GROUPING_ID(Category,Year)<3
ORDER BY 1, 2, GROUPING_ID();
Category | Year | SUM
-------------+------+--------
Books | 2005 | 39.98
Books | 2007 | 29.99
Books | 2008 | 29.99
Books | | 99.96
Electricity | 2005 | 109.99
Electricity | 2006 | 109.99
Electricity | 2007 | 229.98
Electricity | | 449.96