`
csstome
  • 浏览: 1472832 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

ROLLUP 与 CUBE 运算符的使用

 
阅读更多


对于数据的汇总,是数据库经常用到的任务之一,除了我们通常使用的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函数来过滤不需要的结果集。

分享到:
评论

相关推荐

    SQLSERVER中union,cube,rollup,cumpute运算符使用说明

    union,cube,rollup,cumpute运算符的使用技巧。

    Sql学习第四天——SQL 关于with cube,with rollup和grouping解释及演示

    关于with cube ,with rollup 和 grouping 通过查看sql 2005的帮助文档找到了CUBE 和 ROLLUP 之间的具体区别: ...仅在与包含 CUBE 或 ROLLUP 运算符的 GROUP BY 子句相关联的选择列表中才允许分组。 当看到以上

    mrcube:Scalding CUBE 运算符

    Scalding CUBE 运算符 cubify上的简单cubify和rollup方法。 对于每个输入元组 cubify 生成 2^n 个元组,其中 n 是我们正在立方的字段数 rollup 生成 n+1 个元组,其中 n 是我们正在汇总的字段数 开发 $ git clone ...

    SQLServer中汇总功能的使用GROUPING,ROLLUP和CUBE

    用于汇总数据用的运算符: ROLLUP SELECT CASE GROUPING(o.customerid) WHEN 0 THEN o.customerid ELSE ‘(Total)’ END AS AllCustomersSummary, CASE GROUPING(od.orderid) WHEN 0 THEN od....

    Sql Server 分组统计并合计总数及WITH ROLLUP应用

    ROLLUP 运算符生成的结果集类似于 CUBE 运算符所生成的结果集。 代码如下: SELECT [Source], COUNT(*) AS OrderTotal FROM [ExternalOrder] Where OrderStatus=1 AND (CheckPayment=1 ) and TicketDate &gt;= ‘2012-11...

    精通SQL 结构化查询语言详解

    8.3.3 ROLLUP运算符和CUBE运算符  8.3.4 GROUP BY子句中的NULL值处理  8.3.5 HAVING子句  8.3.6 HAVING子句与WHERE子句  8.3.7 SELECT语句各查询子句总结  第9章 多表查询  9.1 本章用到的实例表  ...

    精通SQL--结构化查询语言详解

    8.3.3 rollup运算符和cube运算符 151 8.3.4 group by子句中的null值处理 153 8.3.5 having子句 153 8.3.6 having子句与where子句 154 8.3.7 select语句各查询子句总结 156 第9章 多表查询 157 9.1 本章用到的...

    SQL查询技巧(范例宝典)

     实例325 在分组查询中使用CUBE运算符 475  实例326 在分组查询中使用ROLLUP 477  实例327 对数据进行降序查询 479  实例328 对数据进行多条件排序 480  实例329 对统计结果进行排序 482  实例...

    C#程序开发范例宝典10

    473 实例325 在分组查询中使用CUBE运算符 475 实例326 在分组查询中使用ROLLUP 477 实例327 对数据进行降序查询 479 实例328 对数据进行多条件排序 480 实例329 对统计结果进行排序 482...

    C#程序开发范例宝典(第2版).part08

    第1章 窗体与界面设计 1 1.1 菜单应用实例 2 实例001 带历史信息的菜单 2 实例002 菜单动态合并 3 实例003 像开始菜单一样漂亮的菜单 4 实例004 任务栏托盘菜单 4 实例005 可以拉伸的菜单界面 5 实例006 ...

    C#.net_经典编程例子400个

    273 实例190 获取窗口文本 273 实例191 判断文件是否正在被使用 274 实例192 在程序中调用.HLP文件 275 实例193 C#中实现文件拖放 276 实例194 文件比较 276 第7章 操作系统与Windows...

    C#程序开发范例宝典(第2版).part13

    第1章 窗体与界面设计 1 1.1 菜单应用实例 2 实例001 带历史信息的菜单 2 实例002 菜单动态合并 3 实例003 像开始菜单一样漂亮的菜单 4 实例004 任务栏托盘菜单 4 实例005 可以拉伸的菜单界面 5 实例006 ...

    C#程序开发范例宝典(第2版).part02

    第1章 窗体与界面设计 1 1.1 菜单应用实例 2 实例001 带历史信息的菜单 2 实例002 菜单动态合并 3 实例003 像开始菜单一样漂亮的菜单 4 实例004 任务栏托盘菜单 4 实例005 可以拉伸的菜单界面 5 实例006 ...

    C#程序开发范例宝典(第2版).part12

    第1章 窗体与界面设计 1 1.1 菜单应用实例 2 实例001 带历史信息的菜单 2 实例002 菜单动态合并 3 实例003 像开始菜单一样漂亮的菜单 4 实例004 任务栏托盘菜单 4 实例005 可以拉伸的菜单界面 5 实例006 ...

Global site tag (gtag.js) - Google Analytics