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 子句一起使用

此示例说明如何将 ROLLUPHAVING 子句一起使用,以限制 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

另请参阅