SQL基础之GROUPING
1.grouping sets
记得前几天第一次接触grouping sets时,笔者的感觉是一脸懵逼。
后来一不小心看到msdn上对grouping sets的说明,顿时豁然开朗,其实grouping sets就是由多个group by联合起来,关系如下。
select A , B from table group by grouping sets(A, B) 等价于
select A , null as B from table group by A
union all
select null as A , B from table group by B
为了更好的理解我创建了teacher表,表数据如下,查询结果集中左边的为使用union all的group by字句,右边的为使用grouping sets的结果集。

select null as teacherAddress,MAX(teacherSalary),ascriptionInstitute from teacher group by ascriptionInstitute
union all
select teacherAddress,MAX(teacherSalary),NULL as ascriptionInstitute from teacher group by teacherAddress select teacherAddress,MAX(teacherSalary),ascriptionInstitute from teacher group by GROUPING SETS (ascriptionInstitute,teacherAddress)

上面提到grouping sets是等价于带union all的group by子句,之所以是等价而不是等于,从两者结果集中的对比就可以一目了之,那就是它们的顺序不一样。这说明grouping sets并不只是group by的语法糖,这两者内部的执行过程应该是全然不同的,在百度过程中发现大多数答案都是这句话:“聚合是一次性从数据库中取出所有需要操作的数据,在内存中对数据库进行聚合操作并生成结果。而UNION ALL是多次扫描表,将返回的结果进行UNION操作。性能方面grouping sets能减少IO操作但会增加CPU占用时间”。我不理解的地方是一次性取出数据后,是如何在内存中进行聚合操作的?结果集虽然顺序不一样但数据是相同的,这说明依旧进行了联合操作而这个联合操作并不是多次扫描表,关键内部多次是如何扫描的我很好奇?对于性能我想知道为什么会这样子而不是看到现象。另外在grouping sets中如果将括号中的参数换个位置那么结果也将改变,这说明结果集中的顺序与参数的位置也有关,这让我更加好奇grouping sets的内部执行过程了。
select MAX(teacherSalary),ascriptionInstitute ,teacherAddress from teacher group by GROUPING SETS (ascriptionInstitute,teacherAddress)
select MAX(teacherSalary),ascriptionInstitute ,teacherAddress from teacher group by GROUPING SETS (teacherAddress,ascriptionInstitute)

2.grouping( )
grouping函数用来区分NULL值,这里NULL值有2种情况,一是原本表中的数据就为NULL,二是由rollup、cube、grouping sets生成的NULL值。
当为第一种情况中的空值时,grouping(NULL)返回0;当为第二种情况中的空值时,grouping(NULL)返回1。实例如下,从结果中可以看到第二个结果集中原本为null的数据由于grouping函数为1,故显示ROLLUP-NULL字符串。
select teacherAddress,ascriptionInstitute,COUNT(teacherId ) from teacher group by teacherAddress,ascriptionInstitute
select teacherAddress,ascriptionInstitute,COUNT(teacherId ) from teacher group by rollup(teacherAddress,ascriptionInstitute) select ISNULL(teacherAddress,case when GROUPING(teacherAddress)=1 then 'ROLLUP-NULL' end) as teacherAddress,
ISNULL(ascriptionInstitute,case when GROUPING(ascriptionInstitute)=1 then 'ROLLUP-NULL' end) as ascriptionInstitute,
COUNT(teacherId )
from teacher group by rollup(teacherAddress,ascriptionInstitute)


3.grouping_id( )
grouping_id函数也是计算分组级别的函数,注意如果要使用grouping_id函数那必须得有group by字句,而且group by字句的中的列与grouping_id函数的参数必须相等。比如group by A,B,那么必须使用grouping_id(A,B)。下面用一个等效关系来说明grouping_id()与grouping()的联系,grouping_id(A, B)等效于grouping(A) + grouping(B),但要注意这里的+号不是算术相加,它表示的是二进制数据组合在一起,比如grouping(A)=1,grouping(B)=1,那么grouping_id(A, B)=11B,也就是十进制数3。原来的表数据执行下面的sql语句结果太多效果不明显,所以我改了下表数据,不过对比两个结果集效果很明显。
select ISNULL(teacherAddress,case when GROUPING(teacherAddress)=1 then 'ROLLUP-NULL' end) as teacherAddress,
ISNULL(ascriptionInstitute,case when GROUPING(ascriptionInstitute)=1 then 'ROLLUP-NULL' end) as ascriptionInstitute,
ISNULL(teacherSex,case when GROUPING(teacherSex)=1 then 'ROLLUP-NULL' end) as teacherSex,
COUNT(teacherId )
from teacher group by rollup(teacherAddress,ascriptionInstitute,teacherSex) select ISNULL(teacherAddress,case when GROUPING(teacherAddress)=1 then 'ROLLUP-NULL' end) as teacherAddress,
ISNULL(ascriptionInstitute,case when GROUPING(ascriptionInstitute)=1 then 'ROLLUP-NULL' end) as ascriptionInstitute,
ISNULL(teacherSex,case when GROUPING(teacherSex)=1 then 'ROLLUP-NULL' end) as teacherSex,
COUNT(teacherId ) as '数量' ,
GROUPING_ID(teacherAddress,ascriptionInstitute,teacherSex)
from teacher group by rollup(teacherAddress,ascriptionInstitute,teacherSex)

SQL基础之GROUPING的更多相关文章
- 《SQL基础教程》+ 《SQL进阶教程》 学习笔记
写在前面:本文主要注重 SQL 的理论.主流覆盖的功能范围及其基本语法/用法.至于详细的 SQL 语法/用法,因为每家 DBMS 都有些许不同,我会在以后专门介绍某款DBMS(例如 PostgreSQ ...
- [SQL] SQL 基础知识梳理(一)- 数据库与 SQL
SQL 基础知识梳理(一)- 数据库与 SQL [博主]反骨仔 [原文地址]http://www.cnblogs.com/liqingwen/p/5902856.html 目录 What's 数据库 ...
- [SQL] SQL 基础知识梳理(二) - 查询基础
SQL 基础知识梳理(二) - 查询基础 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5904824.html 序 这是<SQL 基础知识梳理( ...
- [SQL] SQL 基础知识梳理(三) - 聚合和排序
SQL 基础知识梳理(三) - 聚合和排序 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5926689.html 序 这是<SQL 基础知识梳理 ...
- [SQL] SQL 基础知识梳理(四) - 数据更新
SQL 基础知识梳理(四) - 数据更新 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5929786.html 序 这是<SQL 基础知识梳理( ...
- [SQL] SQL 基础知识梳理(五) - 复杂查询
SQL 基础知识梳理(五) - 复杂查询 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5939796.html 序 这是<SQL 基础知识梳理( ...
- 黑马程序员+SQL基础(上)
黑马程序员+SQL基础 ---------------<a href="http://edu.csdn.net"target="blank">ASP ...
- Oracle SQL 基础学习
oracel sql 基础学习 CREATE TABLE USERINFO ( ID ,) PRIMARY KEY, USERNAME ), USERPWD ), EMAIL ), REDATE DA ...
- 第一章 SQL基础
第一部分:SQL基础1. 为什么学习SQL自人类社会形成之日起,社会的运转就在不断地产生和使用各种信息(文献.档案.资料.数据等):在如今所谓的信息时代,由于计算机和互联网的作用,信息的产生和使用达到 ...
随机推荐
- Sql Server之旅——第十站 看看DML操作对索引的影响
我们都知道建索引是需要谨慎的,当只有利大于弊的时候才适合建,我们也知道建索引是需要维护成本的,这个维护也就在于DML操作了, 下面我们具体看看到底DML对索引都有哪些内幕.... 一:delete操作 ...
- 好久没有写博客了,发现Live Writer也更新了
最近由于工作变动,工作内容和心态也有所变化,所以很久没有写博客了,而且我的开源项目深蓝词库转换也很近没有更新了.今天打开LiveWriter发现居然有新版本,于是果断更新.现在新的LiveWriter ...
- MDX函数(官方顺序,带示例)
MDX函数(官方顺序) 1. AddCalculatedMembers (MDX) 返回通过将计算成员添加到指定集而生成的集. 语法: AddCalculatedMembers(Set_Expres ...
- linux添加开机自启动脚本示例详解
linux下(以RedHat为范本)添加开机自启动脚本有两种方法,先来简单的; 一.在/etc/rc.local中添加如果不想将脚本粘来粘去,或创建链接什么的,则:step1. 先修改好脚本,使其所有 ...
- java 重载、重写、构造函数详解
方法重写 1.重写只能出现在继承关系之中.当一个类继承它的父类方法时,都有机会重写该父类的方法.一个特例是父类的方法被标识为final.重写的主要优点是能够定义某个子类型特有的行为. class An ...
- sql in按照指定顺序排序
如下 Select * FROM table1 ,,,,) order by field (3,5,1,4,2)
- Zookeeper C API 指南三(回调函数)(转)
2013-02-21 12:54 by Haippy, 9237 阅读, 0 评论, 收藏, 编辑 接上一篇<Zookeeper C API 指南二(监视(Wathes), 基本常量和结构体介绍 ...
- AC日记——过滤多余的空格 1.7 23
23:过滤多余的空格 总时间限制: 1000ms 内存限制: 65536kB 描述 一个句子中也许有多个连续空格,过滤掉多余的空格,只留下一个空格. 输入 一行,一个字符串(长度不超过200), ...
- 关于OAUTH2.0的极品好文
Web Server Flow: web ServerFlow是把oauth1.0的三个步骤缩略为两个步骤 首先这个是适合有server的第三方使用的. 1客户端http请求authorize 2服务 ...
- sql问题集合
1.sqlparameter @ 写在from前面