当前位置: 首页 > news >正文

[MSSQL]GROUPING SETS,ROLLUP,CUBE初体验

看到某段代码,不懂:

SELECT 
    GROUPING(GRP_A),
    GRP_A,GRP_B,COUNT(0)
FROM T
GROUP BY 
    GROUPING SETS(GRP_A,GRP_B)

于是百度,GOOGLE,MSDN,F1大概有点明白了,是个高级货,GROUP BY 的高级功能,

Inside Microsoft® SQL Server™ 2005 T-SQL Querying中这么解释的,也蛮准确

CUBE | ROLLUP: Supergroups (groups of groups) 

MSSQL2K5新增的关键字,汗颜,6年过去了,今天才知道天地间有这么个东西

心急的朋友不必看完,点此跳转即可,虽然是基于ORACLE的,语法基本一样

除了上述的GROUPING SETS外,还有一些相关的关键字,如

CUBE,ROLLUP,GROUPING SETS

整明白它,搞点基础数据是必须的,嫌麻烦也不行,对我来说算得上是个大活儿了

表及基础数据

CREATE TABLE T(GRP_A VARCHAR(20),GRP_B VARCHAR(20),VAL INT)
INSERT INTO T(GRP_A,GRP_B,VAL)
SELECT 'a1','b1',10 union all
SELECT 'a1','b1',20 union all
SELECT 'a1','b2',30 union all
SELECT 'a1','b2',40 union all
SELECT 'a1','b2',50 union all
 
SELECT 'a2','b3',12 union all
SELECT 'a2','b3',22 union all
SELECT 'a2','b3',32 
 
SELECT * FROM T

F5执行后输出

GRP_A                GRP_B                VAL
-------------------- -------------------- -----------
a1                   b1                   10
a1                   b1                   20
a1                   b2                   30
a1                   b2                   40
a1                   b2                   50
a2                   b3                   12
a2                   b3                   22
a2                   b3                   32

嗯,就这么一张表,目前为止还不算复杂

GROUPING SETS

来对比两段代码,一个使用GROUP,另一个使用GROUPING SETS

SELECT GRP_A,NULL AS GRP_B,COUNT(0) FROM T GROUP BY GRP_A
UNION ALL
SELECT NULL AS GRP_A,GRP_B,COUNT(0) FROM T GROUP BY GRP_B
----------------------------
SELECT 
    GRP_A,GRP_B,COUNT(0)
FROM T
GROUP BY 
    GROUPING SETS(GRP_B,GRP_A)

执行结果一致:

GRP_A                GRP_B                
-------------------- -------------------- -----------
a1                   NULL                 5
a2                   NULL                 3
NULL                 b1                   2
NULL                 b2                   3
NULL                 b3                   3
 
(5 行受影响)
 
GRP_A                GRP_B                
-------------------- -------------------- -----------
a1                   NULL                 5
a2                   NULL                 3
NULL                 b1                   2
NULL                 b2                   3
NULL                 b3                   3
 
(5 行受影响)

第一段代码就是第二段代码的解释,没错,按照GROUPING SETS里的元素分别进行COUNT统计,最后再UNION起来

理解这个GROUPING SETS非常重要,下边的推导就基于它,再看段代码来学习下ROLLUP关键字

ROLLUP

先看两段等效的SQL语句,同样的,前者即是后者的解释:

SELECT
    GRP_A,GRP_B,GRP_C,COUNT(1)
FROM T
GROUP BY
    GROUPING SETS(
        (GRP_A,GRP_B,GRP_C),
        (GRP_A,GRP_B),
        GRP_A,
        ()
    )
ORDER BY 1,2,3,4
-------------------
SELECT
    GRP_A,GRP_B,GRP_C,COUNT(1)
FROM T
GROUP BY
    ROLLUP(GRP_A,GRP_B,GRP_C)
ORDER BY 1,2,3,4

输出相同的结果:

GRP_A                GRP_B                GRP_C                
-------------------- -------------------- -------------------- -----------
NULL                 NULL                 NULL                 8
a1                   NULL                 NULL                 5
a1                   b1                   NULL                 2
a1                   b1                   c1                   1
a1                   b1                   c2                   1
a1                   b2                   NULL                 3
a1                   b2                   c2                   1
a1                   b2                   c3                   2
a2                   NULL                 NULL                 3
a2                   b3                   NULL                 3
a2                   b3                   c3                   3
 
(11 行受影响)
 
GRP_A                GRP_B                GRP_C                
-------------------- -------------------- -------------------- -----------
NULL                 NULL                 NULL                 8
a1                   NULL                 NULL                 5
a1                   b1                   NULL                 2
a1                   b1                   c1                   1
a1                   b1                   c2                   1
a1                   b2                   NULL                 3
a1                   b2                   c2                   1
a1                   b2                   c3                   2
a2                   NULL                 NULL                 3
a2                   b3                   NULL                 3
a2                   b3                   c3                   3
 
(11 行受影响)

多了一列啊,表结构有修改,新的建表脚本如下:

--DROP TABLE T
CREATE TABLE T(GRP_A VARCHAR(20),GRP_B VARCHAR(20),GRP_C VARCHAR(20),VAL INT)
INSERT INTO T(GRP_A,GRP_B,GRP_C,VAL)
SELECT 'a1','b1','c1',10 union all
SELECT 'a1','b1','c2',20 union all
SELECT 'a1','b2','c2',30 union all
SELECT 'a1','b2','c3',40 union all
SELECT 'a1','b2','c3',50 union all
 
SELECT 'a2','b3','c3',12 union all
SELECT 'a2','b3','c3',22 union all
SELECT 'a2','b3','c3',32 
 
SELECT * FROM T

回到刚才那个关键字:ROLLUP

ROLLUP(GRP_A,GRP_B,GRP_C)这一行就等同于

GROUPING SETS(
        (GRP_A,GRP_B,GRP_C),
        (GRP_A,GRP_B),
        GRP_A,
        ()
    )

它又等同什么妮?等同于四个GROUP BY 最后UNION起来!

看上去很像一个"阶乘"效果,递减,就它了,ROLLUP就这么个作用

CUBE

最后看一个关键字:CUBE,它的推导也基于UNION,它与ROLLUP不同的是,会UNION所有组合!

如CUBE(GRP_A,GRP_B,GRP_C)这句与下边这句等效:

GROUPING SETS(
        (GRP_A,GRP_B,GRP_C),
        (GRP_A,GRP_B),
        (GRP_A,GRP_C),
        (GRP_B,GRP_C),
        GRP_A,
        GRP_B,
        GRP_C,
        ()
    )

国际惯例,看两段等效的SQL语句:

SELECT
    GRP_A,GRP_B,GRP_C,COUNT(1)
FROM T
GROUP BY
    GROUPING SETS(
        (GRP_A,GRP_B,GRP_C),
        (GRP_A,GRP_B),
        (GRP_A,GRP_C),
        (GRP_B,GRP_C),
        GRP_A,
        GRP_B,
        GRP_C,
        ()
    )
ORDER BY 1,2,3,4
-------------------
SELECT
    GRP_A,GRP_B,GRP_C,COUNT(1)
FROM T
GROUP BY
    CUBE(GRP_A,GRP_B,GRP_C)
ORDER BY 1,2,3,4

两者的输出一致滴,如下:

GRP_A                GRP_B                GRP_C                
-------------------- -------------------- -------------------- -----------
NULL                 NULL                 NULL                 8
NULL                 NULL                 c1                   1
NULL                 NULL                 c2                   2
NULL                 NULL                 c3                   5
NULL                 b1                   NULL                 2
NULL                 b1                   c1                   1
NULL                 b1                   c2                   1
NULL                 b2                   NULL                 3
NULL                 b2                   c2                   1
NULL                 b2                   c3                   2
NULL                 b3                   NULL                 3
NULL                 b3                   c3                   3
a1                   NULL                 NULL                 5
a1                   NULL                 c1                   1
a1                   NULL                 c2                   2
a1                   NULL                 c3                   2
a1                   b1                   NULL                 2
a1                   b1                   c1                   1
a1                   b1                   c2                   1
a1                   b2                   NULL                 3
a1                   b2                   c2                   1
a1                   b2                   c3                   2
a2                   NULL                 NULL                 3
a2                   NULL                 c3                   3
a2                   b3                   NULL                 3
a2                   b3                   c3                   3
 
(26 行受影响)
 
GRP_A                GRP_B                GRP_C                
-------------------- -------------------- -------------------- -----------
NULL                 NULL                 NULL                 8
NULL                 NULL                 c1                   1
NULL                 NULL                 c2                   2
NULL                 NULL                 c3                   5
NULL                 b1                   NULL                 2
NULL                 b1                   c1                   1
NULL                 b1                   c2                   1
NULL                 b2                   NULL                 3
NULL                 b2                   c2                   1
NULL                 b2                   c3                   2
NULL                 b3                   NULL                 3
NULL                 b3                   c3                   3
a1                   NULL                 NULL                 5
a1                   NULL                 c1                   1
a1                   NULL                 c2                   2
a1                   NULL                 c3                   2
a1                   b1                   NULL                 2
a1                   b1                   c1                   1
a1                   b1                   c2                   1
a1                   b2                   NULL                 3
a1                   b2                   c2                   1
a1                   b2                   c3                   2
a2                   NULL                 NULL                 3
a2                   NULL                 c3                   3
a2                   b3                   NULL                 3
a2                   b3                   c3                   3
 
(26 行受影响)
 
 
推荐乡亲们去原站学习去, 点我跳转
 
简单总结下
1,CUBE(1,2,3)等效于
GROUPING SETS(
(1,2,3),
(1,2),
(1,3),
(2,3),
1,
2,
3,
()
)
 
2,ROLLUP(1,2,3)等效于

GROUPING SETS(
        (1,2,3),
        (1,2),
        1,
        ()
    )

3,GROUPING sets(1,2)等效于

SELECT 1,COUNT FROM T GROUP BY 1 UNION ALL

SELECT 2,COUNT FROM T GROUP BY 2(伪代码)

有不对的,错误的地方还请多多包涵,我相信不写出来就很难发现自己理解错误或偏差的地方,多提宝贵意见,回复有时候比文章好看!

参考资料

http://www.sqlsnippets.com/en/topic-13128.html

http://download.oracle.com/docs/cd/B28359_01/server.111/b28313/aggreg.htm#i1007021

 

猜测您可能对下边的文章感兴趣

SQL SERVER 2008 函数大全 - 字符串函数

SQL2008系统统计函数

[MSSQL]GROUPING SETS,ROLLUP,CUBE初体验

[MSSQL]ROW_NUMBER函数

[MSQL]RANK函数

[MSSQL]NTILE另类分页有么有?!

[MSQL]也说SQL中显示星期几函数

[MSSQL]COALESCE与ISNULL函数

[MSSQL]PIVOT函数

[MSSQL]FOR XML AUTO I

[MSSQL]FOR XML AUTO II

[MSSQL]TRY…CATCH…通用格式

如果您喜欢该博客请点击右下角推荐按钮,您的推荐是作者创作的动力!

 

 

转载于:https://www.cnblogs.com/kkun/archive/2011/08/10/2133613.html

相关文章:

  • Android系统特质 不需要太多剩余内存
  • 转:SQLServer2000 数据库事务日志备份
  • Android ADB命令的使用
  • 嵌入式中linu+android与wince的区别
  • Struts2与Struts1的对比
  • memcache 管理指令 --stats
  • ListView(二)
  • Flex--水晶按钮
  • Links to sample code for the Windows Phone 7
  • [30期] 我的学习方法
  • 莫名的PAMIE错误
  • Apache2.2虚拟主机添加多域名
  • 一起谈.NET技术,使用VS2010为Windows7编写一个杀手级WPF应用
  • HDU_1158 Employment Planning(DP)
  • 如何解决文件夹不能删除的情况
  • [PHP内核探索]PHP中的哈希表
  • [数据结构]链表的实现在PHP中
  • 【407天】跃迁之路——程序员高效学习方法论探索系列(实验阶段164-2018.03.19)...
  • 11111111
  • conda常用的命令
  • css属性的继承、初识值、计算值、当前值、应用值
  • input的行数自动增减
  • JS进阶 - JS 、JS-Web-API与DOM、BOM
  • Linux学习笔记6-使用fdisk进行磁盘管理
  • SegmentFault 社区上线小程序开发频道,助力小程序开发者生态
  • vue学习系列(二)vue-cli
  • 关于extract.autodesk.io的一些说明
  • 好的网址,关于.net 4.0 ,vs 2010
  • 前端每日实战:70# 视频演示如何用纯 CSS 创作一只徘徊的果冻怪兽
  • 使用docker-compose进行多节点部署
  • 事件委托的小应用
  • 微服务核心架构梳理
  • 限制Java线程池运行线程以及等待线程数量的策略
  • nb
  • MyCAT水平分库
  • ​LeetCode解法汇总2696. 删除子串后的字符串最小长度
  • ​人工智能书单(数学基础篇)
  • ​如何在iOS手机上查看应用日志
  • #[Composer学习笔记]Part1:安装composer并通过composer创建一个项目
  • #define,static,const,三种常量的区别
  • #stm32驱动外设模块总结w5500模块
  • #vue3 实现前端下载excel文件模板功能
  • (+4)2.2UML建模图
  • (14)目标检测_SSD训练代码基于pytorch搭建代码
  • (2)(2.10) LTM telemetry
  • (BFS)hdoj2377-Bus Pass
  • (Python第六天)文件处理
  • (Spark3.2.0)Spark SQL 初探: 使用大数据分析2000万KF数据
  • (附源码)springboot车辆管理系统 毕业设计 031034
  • (附源码)ssm高校实验室 毕业设计 800008
  • (转)h264中avc和flv数据的解析
  • .mysql secret在哪_MySQL如何使用索引
  • .net core 6 redis操作类
  • .net core 依赖注入的基本用发
  • .NET 表达式计算:Expression Evaluator