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的更多相关文章

  1. 《SQL基础教程》+ 《SQL进阶教程》 学习笔记

    写在前面:本文主要注重 SQL 的理论.主流覆盖的功能范围及其基本语法/用法.至于详细的 SQL 语法/用法,因为每家 DBMS 都有些许不同,我会在以后专门介绍某款DBMS(例如 PostgreSQ ...

  2. [SQL] SQL 基础知识梳理(一)- 数据库与 SQL

    SQL 基础知识梳理(一)- 数据库与 SQL [博主]反骨仔 [原文地址]http://www.cnblogs.com/liqingwen/p/5902856.html 目录 What's 数据库 ...

  3. [SQL] SQL 基础知识梳理(二) - 查询基础

    SQL 基础知识梳理(二) - 查询基础 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5904824.html 序 这是<SQL 基础知识梳理( ...

  4. [SQL] SQL 基础知识梳理(三) - 聚合和排序

    SQL 基础知识梳理(三) - 聚合和排序 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5926689.html 序 这是<SQL 基础知识梳理 ...

  5. [SQL] SQL 基础知识梳理(四) - 数据更新

    SQL 基础知识梳理(四) - 数据更新 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5929786.html 序 这是<SQL 基础知识梳理( ...

  6. [SQL] SQL 基础知识梳理(五) - 复杂查询

    SQL 基础知识梳理(五) - 复杂查询 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5939796.html 序 这是<SQL 基础知识梳理( ...

  7. 黑马程序员+SQL基础(上)

    黑马程序员+SQL基础 ---------------<a href="http://edu.csdn.net"target="blank">ASP ...

  8. Oracle SQL 基础学习

    oracel sql 基础学习 CREATE TABLE USERINFO ( ID ,) PRIMARY KEY, USERNAME ), USERPWD ), EMAIL ), REDATE DA ...

  9. 第一章 SQL基础

    第一部分:SQL基础1. 为什么学习SQL自人类社会形成之日起,社会的运转就在不断地产生和使用各种信息(文献.档案.资料.数据等):在如今所谓的信息时代,由于计算机和互联网的作用,信息的产生和使用达到 ...

随机推荐

  1. JavaScript Patterns 6.2 Expected Outcome When Using Classical Inheritance

    // the parent constructor function Parent(name) { this.name = name || 'Adam'; } // adding functional ...

  2. Learning The Bash Shell读书笔记(整理)

    最近搞了一本书 Learning Bash Shell,发现有人已经写了阅读笔记,我就在这边整理一下 来自blog:http://blog.sina.com.cn/n4mine Learning Th ...

  3. mysql-mmm 安装配置(双主)

    原文地址:mysql-mmm 安装配置 作者:chinaunix1116 MMM即Master-Master Replication Managerfor MySQL(mysql主主复制管理器)关于m ...

  4. 讲讲js中的逻辑与(&&)以及逻辑或(||)

    前几天看到一个函数,百思不得其解,今天早上醒来看了本js的书,正好讲到操作符的用法,给大家分享下js中的&&,||,和我们用的其他的编程语言还是有点区别的. 直接上那个函数的代码: f ...

  5. 使用bakefile编译C工程代码

    前言 最近有个想法,想把ineedle整体架构从头自己编写代码来实现一下,来加深对iNeedle系统的理解,同时加强Linux + C相关知识.由于iNeedle系统的庞大,只能是先把框架搭起来,根据 ...

  6. 安装DELL R430服务器的过程记录

    序: 本次需要安装一个ineedle设备给客户用,貌似客户是华三.这次领导比较重视,下血本买了一台DELL服务器,似乎花费了1万多大洋.当然配置是比较高了,CPU:Intel(R) Xeon(R) C ...

  7. Android Paint类方法说明

    * Paint类介绍 * * Paint即画笔,在绘图过程中起到了极其重要的作用,画笔主要保存了颜色, * 样式等绘制信息,指定了如何绘制文本和图形,画笔对象有很多设置方法, * 大体上可以分为两类, ...

  8. android JAVA字符串转日期或日期转字符串(转)

    用法: SimpleDateFormat sdf = new SimpleDateFormat( " yyyy-MM-dd HH:mm:ss " ); 这一行最重要,它确立了转换的 ...

  9. HTTP 请求报文 响应报文

    引言 超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议.所有的WWW文件都必须遵守这个标准.设计HTTP最初的目的是为了提供一种发 ...

  10. LNMP源码安装

    1. mysql安装 # Preconfiguration setup shell > groupadd mysql shell > useradd -r -g mysql -s /bin ...