PostgreSQL教程-查询-FROM子句-GROUPING SETS、CUBE和ROLLUP
最新学讯:近期OCP认证正在报名中,因考试人员较多请尽快报名获取最近考试时间,报名费用请联系在线老师,甲骨文官方认证,报名从速!
我要咨询7.2.4. GROUPING SETS、CUBE和ROLLUP
使用分组集的概念可以实现比上述更加复杂的分组操作。由 FROM和WHERE子句选出的数据被按照每一个指定 的分组集单独分组,按照简单GROUP BY子句对每一个分组计算 聚集,然后返回结果。例如:
=> SELECT * FROM items_sold;
brand | size | sales
-------+------+-------
Foo | L | 10
Foo | M | 20
Bar | M | 15
Bar | L | 5
(4 rows)
=> SELECT brand, size, sum(sales) FROM items_sold GROUP BY GROUPING SETS ((brand), (size), ());
brand | size | sum
-------+------+-----
Foo | | 30
Bar | | 20
| L | 15
| M | 35
| | 50
(5 rows)
GROUPING SETS的每一个子列表可以指定一个或者多个列或者表达式, 它们将按照直接出现在GROUP BY子句中同样的方式被解释。一个空的 分组集表示所有的行都要被聚集到一个单一分组(即使没有输入行存在也会被输出) 中,这就像前面所说的没有GROUP BY子句的聚集函数的情况一样。
对于分组列或表达式没有出现在其中的分组集的结果行,对分组列或表达式的引用会 被空值所替代。要区分一个特定的输出行来自于哪个分组,请见 表 9.59。
PostgreSQL 中提供了一种简化方法来指定两种常用类型的分组集。下面形式的子句
ROLLUP ( e1, e2, e3, ... )
表示给定的表达式列表及其所有前缀(包括空列表),因此它等效于
GROUPING SETS (
( e1, e2, e3, ... ),
...
( e1, e2 ),
( e1 ),
( )
)
这通常被用来分析历史数据,例如按部门、区和公司范围计算的总薪水。
下面形式的子句
CUBE ( e1, e2, ... )
表示给定的列表及其可能的子集(即幂集)。因此
CUBE ( a, b, c )
等效于
GROUPING SETS (
( a, b, c ),
( a, b ),
( a, c ),
( a ),
( b, c ),
( b ),
( c ),
( )
)
CUBE或ROLLUP子句中的元素可以是表达式或者 圆括号中的元素子列表。在后一种情况中,对于生成分组集的目的来说,子列 表被当做单一单元来对待。例如:
CUBE ( (a, b), (c, d) )
等效于
GROUPING SETS (
( a, b, c, d ),
( a, b ),
( c, d ),
( )
)
并且
ROLLUP ( a, (b, c), d )
等效于
GROUPING SETS (
( a, b, c, d ),
( a, b, c ),
( a ),
( )
)
CUBE和ROLLUP可以被直接用在 GROUP BY子句中,也可以被嵌套在一个 GROUPING SETS子句中。如果一个 GROUPING SETS子句被嵌套在另一个同类子句中, 效果和把内层子句的所有元素直接写在外层子句中一样。
如果在一个GROUP BY子句中指定了多个分组项,那么最终的 分组集列表是这些项的叉积。例如:
GROUP BY a, CUBE (b, c), GROUPING SETS ((d), (e))
等效于
GROUP BY GROUPING SETS (
(a, b, c, d), (a, b, c, e),
(a, b, d), (a, b, e),
(a, c, d), (a, c, e),
(a, d), (a, e)
)
注意
在表达式中,结构(a, b)通常被识别为一个 a 行构造器。在 GROUP BY子句中,这不会在表达式的顶层应用,并且 (a, b)会按照上面所说的被解析为一个表达式的列表。如果出于 某种原因你在分组表达式中需要一个行构造器,请使用 ROW(a, b)。