ROLLUP 与 CUBE 运算符的使用

简介:     对于数据的汇总,是数据库经常用到的任务之一,除了我们通常使用的GROUP BY分组配合聚合函数对数据汇总,以及使用UNION ALL 对数据汇总之外,SQL还提供了 GROUP BY Col1,Col2.. WITH CUBE | ROLLUP,以及COMPUTE BY 等汇总方式,本文主要介绍了使用CUBE 与ROLLUP运算符来实现数据的分级汇总。


    对于数据的汇总,是数据库经常用到的任务之一,除了我们通常使用的GROUP BY分组配合聚合函数对数据汇总,以及使用UNION ALL 对数据汇总之外,SQL还提供了 GROUP BY Col1,Col2.. WITH CUBE | ROLLUP,以及COMPUTE BY 等汇总方式,本文主要介绍了使用CUBE 与ROLLUP运算符来实现数据的分级汇总。


IF OBJECT_ID('tb') IS NOT NULL
 DROP TABLE tb;
GO  
CREATE TABLE tb
(
    Provider    VARCHAR(10)
    ,MaterialNo VARCHAR(3)
    ,Quantity INT
   
); 
INSERT INTO tb SELECT 'Canon',  '001',  500 
UNION ALL SELECT 'Canon',  '001',     200 
UNION ALL SELECT 'Canon',  '002',     100
UNION ALL SELECT 'Canon',  '002',     300
UNION ALL SELECT 'Sony',  '001',     200 
UNION ALL SELECT 'IBM',  '002',     100 
UNION ALL SELECT 'IBM',  '001',     600 
UNION ALL SELECT 'IBM',  '001',     200  

 

--1.使用ROLLUP来对数据进行汇总
SELECT Provider,MaterialNo,SUM(Quantity) AS Sum_Quantity FROM tb
GROUP BY Provider,MaterialNo
WITH ROLLUP
/*  --结果
Provider   MaterialNo Sum_Quantity
---------- ---------- ------------
Canon      001        700
Canon      002        400
Canon      NULL       1100
IBM        001        800
IBM        002        100
IBM        NULL       900
Sony       001        200
Sony       NULL       200
NULL       NULL       2200
*/
由结果可以得知,ROLLUP运算符实现了对Provider级别进行汇总,结果集中Provider字段不为空,MaterialNo字段为空的时候实现了对不同的Provider分类汇总,而当Provider与MaterialNo都为空时则是对所有的Provider来实现数据汇总。

 

--2.使用CUBE来对数据进行汇总
SELECT Provider,MaterialNo,SUM(Quantity) AS Sum_Quantity FROM tb
GROUP BY Provider,MaterialNo
WITH CUBE
/*  --结果
Provider   MaterialNo Sum_Quantity
---------- ---------- ------------
Canon      001        700
Canon      002        400
Canon      NULL       1100
IBM        001        800
IBM        002        100
IBM        NULL       900
Sony       001        200
Sony       NULL       200
NULL       NULL       2200
NULL       001        1700
NULL       002        500
*/
与ROLLUP相比,从结果可以看出CUBE的结果集在ROLLUP结果集的基础上增加了两行,
NULL       001        1700
NULL       002        200
即对不同MaterialNo也实现了汇总。

 

--3.ROLLUP与CUBE的差异
 . ROLLUP 生成的结果集为所选列中值的某一维度的聚合。如以上示例中实现了对Provider维度进行汇总。
 . CUBE  生成的结果集为所选列中值的所有维度的聚合。如以上示例中实现了对Provider和MaterialNo所有维度进行汇总。
 
--4.使用GROUPING函数来处理汇总产生的NULL值
     对于使用ROLLUP与CUBE汇总数据所产生的NULL值,容易引起与实际数据本身为NULL容易引起歧义,对此我们可以使用GROUPING函数的进行区分。
     当NULL为ROLLUP或CUBE所产生时,则GROUPING函数返回的值为1,当NULL来自实际数据本身的话,GROUPING函数返回的值为0。
SELECT
    CASE WHEN (GROUPING(Provider) = 1) THEN 'ALL'
         ELSE Provider END AS Provider,
    CASE WHEN (GROUPING(MaterialNo) = 1) THEN 'ALL'
         ELSE MaterialNo END AS MaterialNo,
    SUM(Quantity) AS Sum_Quantity FROM tb
GROUP BY Provider,MaterialNo
WITH CUBE 
/*  --结果
Provider   MaterialNo Sum_Quantity
---------- ---------- ------------
Canon      001        700
Canon      002        400
Canon      ALL        1100
IBM        001        800
IBM        002        100
IBM        ALL        900
Sony       001        200
Sony       ALL        200
ALL        ALL        2200
ALL        001        1700
ALL        002        500
*/

 

--5.使用Having子句来顾虑掉无用的数据,比如本例过滤掉了总计以及MaterialNo汇总的数据。
SELECT
    CASE WHEN (GROUPING(Provider) = 1) THEN 'ALL'
         ELSE Provider END AS Provider,
    CASE WHEN (GROUPING(MaterialNo) = 1) THEN 'ALL'
         ELSE MaterialNo END AS MaterialNo,
    SUM(Quantity) AS Sum_Quantity FROM tb
GROUP BY Provider,MaterialNo WITH CUBE
HAVING GROUPING(Provider) <> 1
/*  --结果
Provider   MaterialNo Sum_Quantity
---------- ---------- ------------
Canon      001        700
Canon      002        400
Canon      ALL        1100
IBM        001        800
IBM        002        100
IBM        ALL        900
Sony       001        200
Sony       ALL        200
*/

 

--过滤掉了相同Provider,不同的MaterialNo 的小计数据和最终的总计数据
SELECT
    CASE WHEN (GROUPING(Provider) = 1) THEN 'ALL'
         ELSE Provider END AS Provider,
    CASE WHEN (GROUPING(MaterialNo) = 1) THEN 'ALL'
         ELSE MaterialNo END AS MaterialNo,
    SUM(Quantity) AS Sum_Quantity FROM tb
GROUP BY Provider,MaterialNo WITH CUBE
HAVING GROUPING(MaterialNo) = 0

 

总结:CUBE,ROLLUP为多维数据集的汇总提供了可能,当需要对所有维度进行汇总,应当使用CUBE运算符,对某一维度进行汇总则使用ROLLUP运算法。
     需要注意的是,WITH CUBE | ROLLUP必须跟在GROUP BY Col1,Col2列之后,然后可以通过使用HAVING子句配合GROUPING函数来过滤不需要的结果集。

目录
相关文章
|
7月前
|
JavaScript 前端开发 开发者
深入了解rollup(一)快速开始
Rollup 是一个用于 JavaScript 的模块打包工具,它将小的代码片段编译成更大、更复杂的代码,例如库或应用程序。它使用 JavaScript 的 ES6 版本中包含的新标准化代码模块格式,而不是以前的 CommonJS 和 AMD 等特殊解决方案。ES 模块允许你自由无缝地组合你最喜欢的库中最有用的个别函数。这在未来将在所有场景原生支持,但 Rollup 让你今天就可以开始这样做。
95 0
|
SQL 数据挖掘 关系型数据库
Hive 高阶--分组窗口函数--OLAP 相关分组函数(GROUPING SETS,CUBE,ROLLUP)|学习笔记
快速学习 Hive 高阶--分组窗口函数--OLAP 相关分组函数(GROUPING SETS,CUBE,ROLLUP)
237 0
Hive 高阶--分组窗口函数--OLAP 相关分组函数(GROUPING SETS,CUBE,ROLLUP)|学习笔记
|
SQL 关系型数据库
【笔记】开发指南—DQL语句—Grouping Sets、Rollup和Cube扩展
在关系型数据库中,通常需要使用多个SELECT + UNION语句来实现按照多组维度的结果分组,PolarDB-X新增支持通过Grouping Sets、Rollup和Cube扩展来实现这一目的。此外,PolarDB-X还支持在SELECT命令或HAVING子句中使用GROUPING函数和GROUPING_ID函数,来帮助解释使用上述扩展时的结果。本文将介绍相关语法和示例。
115 0
|
SQL 关系型数据库 Linux
开发指南—DQL语句—Grouping Sets、Rollup和Cube扩展
在关系型数据库中,通常需要使用多个SELECT + UNION语句来实现按照多组维度的结果分组,PolarDB-X新增支持通过Grouping Sets、Rollup和Cube扩展来实现这一目的。此外,PolarDB-X还支持在SELECT命令或HAVING子句中使用GROUPING函数和GROUPING_ID函数,来帮助解释使用上述扩展时的结果。本文将介绍相关语法和示例。
142 0
|
关系型数据库
PolarDB-X 1.0-SQL 手册-函数-Grouping Sets、Rollup和Cube扩展
在关系型数据库中,通常需要使用多个SELECT + UNION语句来实现按照多组维度的结果分组,PolarDB-X新增支持通过Grouping Sets、Rollup和Cube扩展来实现这一目的。此外,PolarDB-X还支持在SELECT命令或HAVING子句中使用GROUPING函数和GROUPING_ID函数,来帮助解释使用上述扩展时的结果。本文将介绍相关语法和示例。
175 0
[20171219]Cube, Grouping and Rollup.txt
[20171219]Cube, Grouping and Rollup.txt --//每到年底.总有一些报表统计之类的事情,这些事情非常繁琐,报表往往是一次性,写sql语句非常耗费时间.
1234 0