1029.查询-复杂分组grouping子句

使用分组集的概念可以实现比上述更加复杂的分组操作。

由 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子句的聚集函数的情况一样。

对于分组列或表达式没有出现在其中的分组集的结果行,对分组列或表达式的引用会 被空值所替代。要区分一个特定的输出行来自于哪个分组

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)。

原文地址:https://www.cnblogs.com/bufuzhou/p/14244185.html