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
子句的聚集函数的情况一样。
对于分组列或表达式没有出现在其中的分组集的结果行,对分组列或表达式的引用会被空值所替代。
KingbaseES
中提供了一种简化方法来指定两种常用类型的分组集。下面形式的子句
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)
)
Note:
在表达式中,结构
(a, b)
通常被识别为一个
a
行构造器。在
GROUP BY
子句中,不会在表达式的
顶层应用,并且
(a, b)
会按照上面所说的被解析为一个表达式的列表。如果出于某种原因在分组表达式中
需要一个行构造器,请使用
ROW(a, b)
。