多级聚合
过一段时间后,经常更新的表可能会包含大量数据。以之前所示的简单表为例,假设您想要执行多级别查询,例如查询每年在每个类别上的开支金额。
以下查询使用了具有 SUM 函数的 ROLLUP
聚合,可计算各个类别的总开支和所有总开支。NULL 字段表示聚合中的小计值。
-
只有当
Year
列为NULL
时,小计才是针对所有Category
值。 -
当
Year
和Category
列为NULL
时,小计针对两个列的所有Amount
值。
使用 ORDER BY
子句,按开支类别、发生开支的年份以及 GROUPING_ID
函数创建的 GROUP BY
级别对结果进行排序:
=> SELECT Category, Year, SUM(Amount) FROM expenses
GROUP BY ROLLUP(Category, Year) ORDER BY Category, Year, GROUPING_ID();
Category | Year | SUM
------------+------+--------
Books | 2005 | 39.98
Books | 2007 | 29.99
Books | 2008 | 29.99
Books | | 99.96
Electrical | 2005 | 109.99
Electrical | 2006 | 109.99
Electrical | 2007 | 229.98
Electrical | | 449.96
| | 549.92
同样地,以下查询计算了各年份的总销售以及所有销售总额,然后使用 ORDER BY
子句来对结果进行排序:
=> SELECT Category, Year, SUM(Amount) FROM expenses
GROUP BY ROLLUP(Year, Category) ORDER BY 2, 1, GROUPING_ID();
Category | Year | SUM
------------+------+--------
Books | 2005 | 39.98
Electrical | 2005 | 109.99
| 2005 | 149.97
Electrical | 2006 | 109.99
| 2006 | 109.99
Books | 2007 | 29.99
Electrical | 2007 | 229.98
| 2007 | 259.97
Books | 2008 | 29.99
| 2008 | 29.99
| | 549.92
(11 rows)
您可以使用 CUBE
聚合来执行所有可能的类别和年份开支分组。以下查询按分组进行了排序,并返回了所有可能的分组:
=> SELECT Category, Year, SUM(Amount) FROM expenses
GROUP BY CUBE(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
Electrical | 2005 | 109.99
Electrical | 2006 | 109.99
Electrical | 2007 | 229.98
Electrical | | 449.96
| 2005 | 149.97
| 2006 | 109.99
| 2007 | 259.97
| 2008 | 29.99
| | 549.92
结果包括每个类别每年的小计以及不分年份或类别的所有交易的总计 ($549.92)。
ROLLUP
、CUBE
和 GROUPING SETS
在分组列生成了 NULL
值以确定小计。如果表数据包括 NULL
值,将这些值与小计中的 NULL
值区分有时非常具有挑战性。
在之前的输出中,Year
列中的 NULL
值表示行在 Category
列(而不是在两个列)进行了分组。在这种情况下,ROLLUP
添加了 NULL
值,以表示小计行。