原文地址:http://blog.csdn.net/u014558001/article/details/42387929

本文主要讲解 ROLLUP, CUBE, GROUPING SETS的主要用法,这些函数可以理解为GroupBy分组函数封装后的精简用法,相当于多个union all 的组合显示效果,但是要比 多个union all的效率要高。

其实这些函数在时间的程序开发中应用的并不多,至少在我工作的多年时间中没用过几次,因为现在的各种开发工具/平台都自带了这些高级分组统计功能,使用的方便性及美观性都比这些要好。但如果临时查下数据,用这些函数还是不错的。

创建测试环境

1.      创建表

  1. createtable EMP2
  2. (
  3. ID       NUMBER,  -- 员工编号
  4. NAME     VARCHAR2(20), --姓名
  5. SEX     VARCHAR2(2),  --性别
  6. HIREDATE DATE,         --入职日期
  7. BASE    VARCHAR2(20), --工作母地
  8. DEPT    VARCHAR2(20), --所在部门
  9. SAL     NUMBER        --月工资
  10. );

2.      插入测试数据

  1. insert into emp2 (ID, NAME, SEX, HIREDATE,BASE, DEPT, SAL)
  2. values (107, '小月', '女', to_date('01-09-2013', 'dd-mm-yyyy'), '北京','营运', 9000);
  3. insert into emp2 (ID, NAME, SEX, HIREDATE,BASE, DEPT, SAL)
  4. values (108, '小美', '女', to_date('01-06-2011', 'dd-mm-yyyy'), '上海','营运', 11000);
  5. insert into emp2 (ID, NAME, SEX, HIREDATE,BASE, DEPT, SAL)
  6. values (101, '张三', '男', to_date('01-01-2011', 'dd-mm-yyyy'), '北京','财务', 8000);
  7. insert into emp2 (ID, NAME, SEX, HIREDATE,BASE, DEPT, SAL)
  8. values (102, '李四', '男', to_date('01-01-2012', 'dd-mm-yyyy'), '北京','营运', 15000);
  9. insert into emp2 (ID, NAME, SEX, HIREDATE,BASE, DEPT, SAL)
  10. values (103, '王五', '男', to_date('01-01-2013', 'dd-mm-yyyy'), '上海','营运', 6000);
  11. insert into emp2 (ID, NAME, SEX, HIREDATE,BASE, DEPT, SAL)
  12. values (104, '赵六', '男', to_date('01-01-2014', 'dd-mm-yyyy'), '上海','财务', 10000);
  13. insert into emp2 (ID, NAME, SEX, HIREDATE,BASE, DEPT, SAL)
  14. values (105, '小花', '女', to_date('01-08-2014', 'dd-mm-yyyy'), '上海','财务', 4000);
  15. insert into emp2 (ID, NAME, SEX, HIREDATE,BASE, DEPT, SAL)
  16. values (106, '小静', '女', to_date('01-01-2015', 'dd-mm-yyyy'), '北京','财务', 6000);
  17. commit;

3.     查看一下刚才插入的数据

  1. select * from emp2;

 

4.      先看下普通分组的效果

按照地区统计每个部门的总工资

  1. select base,dept ,sum(sal) from emp2
  2. group by base,dept;

查看结果如下:

ROLLUP(累计累加)

ROLLUP是对group by的扩展,因此,它只能出现在group
by子句中,依赖于分组的列,对每个分组会生成汇总数据, rollup和group by联合一起使用,达到了按group
by列顺序分组,并且实现小计和合计的功能。rollup分组还是有序的,先全部分组,然后对每个分组小计,最后合计。

rollup中列的顺序不同,则统计的结果不同。因为它是按列从右递减分组的。

比如 Group by  ROLLUP(A, B, C),首先会对(A、B、C)进行GROUP BY,然后对(A、B)进行GROUP BY,然后是(A)进行GROUP BY,最后对全表进行GROUP BY操作

按照地区统计每个部门的总工资,按工作母地汇总,再合计

  1. select base,dept,sum(sal) from emp2
  2. groupbyrollup(base,dept);

结果相当于

  1. select base,dept,sum(sal) from emp2
  2. group by base,dept
  3. unionall
  4. select base,null,sum(sal) from emp2
  5. group by base,null
  6. unionall
  7. selectnull,null,sum(sal) from emp2
  8. group by null,null
  9. order by 1,2

如果颠倒下rollup顺序则结果如下:

  1. select base,dept,sum(sal) from emp2
  2. group by rollup(dept,base);

如果在实际查询中,有的小计或合计我们不需要,那么就要使用局部rollup,局部rollup就是将需要固定统计的列放在group by中,而不是放在rollup中。

  1. select base,dept,sum(sal) from emp2
  2. group by dept,rollup(base);

与group by rollup(dept,base)相比:去掉了最后一行的汇总,因为每次汇总要么是dept,base,要么是dept,null ,dept是固定的。

如果只希望看到合计则可以这样写:

  1. select base,dept ,sum(sal) from emp2
  2. group by rollup((base,dept));

CUBE(交叉列表)

CUBE也是对group by运算的一种扩展,它比rollup扩展更加精细,组合类型更多,rollup是按组合的列从右到左递减分组计算,而CUBE则是对所有可能的组合情况进行分组,这样分组的情况更多,覆盖所有的可能分组,并计算所有可能的分组的小计。

对于CUBE来说,列的名字只要一样,那么顺序无所谓,结果都是一样的,因为cube是各种可能情况的组合,只不过统计的结果顺序不同而已。但是对于rollup来说,列的顺序不同,则结果不同。

比如对工作母地和部门的交叉统计

  1. select base,dept,sum(sal) from emp2
  2. group by cube(base,dept)
  3. order by 1,2;

部分CUBE和部分ROLLUP类似,把需要固定统计的列放到group by中,不放到cube中就可以了。

如果cube中只有一个列,那么和rollup的结果一致

  1. select base,dept,sum(sal) from emp2
  2. group by dept,cube(base)
  3. order by1,2;

rollup和cube区别:

如果是ROLLUP(A,B, C)的话,GROUP BY顺序

(A、B、C)

(A、B)

(A)

最后对全表进行GROUPBY操作。

如果是GROUP BY CUBE(A, B, C),GROUP BY顺序
(A、B、C)

(A、B)

(A、C)

(A),

(B、C)

(B)

(C),

最后对全表进行GROUPBY操作。

GROUPING SETS

对group by的另一个扩展,专门对分组列分别进行小计计算,不包括合计。使用方式和rollup和cube一样,都是放在group by中。

比如需要分别统计工作母地与部门的合计:

  1. select base,dept,sum(sal) from emp2
  2. group by grouping sets(base,dept);

结果为:

等价于

  1. select base,null,sum(sal) from emp2
  2. group by  base,null
  3. unionall
  4. select null,dept,sum(sal) from emp2
  5. group by  null,dept;

理解了groupingsets的原理我们用他实现rollup的功能也是可以的:

  1. select base,dept,sum(sal) from emp2
  2. group by grouping sets ((base,dept),dept,null);

效果如下:

grouping函数

在以上例子中,是用rollup和cube函数都会对结果集产生null,这时候可用grouping函数来确认该记录是由哪个字段得出来的

grouping函数用法,带一个参数,参数为字段名,结果是根据该字段得出来的就返回1,反之返回0

例如:

  1. select decode(grouping(base),1,'所有地区',base) base,
  2. decode(grouping(dept),1,'所有部门',dept)dept ,sum(sal) from emp2
  3. group by rollup(dept,base);

更多ROLLUP,CUBE, GROUPING SETS与GROUP BY的关系可以参考Oracle官方文档中的例子

http://docs.oracle.com/cd/E11882_01/server.112/e25554/aggreg.htm#DWHSG8608

[转]详解Oracle高级分组函数(ROLLUP, CUBE, GROUPING SETS)的更多相关文章

  1. 高级聚合函数rollup(),cube(),grouping sets()

       rollup(),cube(),grouping sets()   上面这几个函数,是对group by分组功能做的功能扩展. a.rollup()   功能:在原结果基础上追加一行总合计记录 ...

  2. oracle 高级分组

    oracle 高级分组 博客分类: 数据库基础 oraclesql  10.高级分组 本章目标: 对于增强的group by需要掌握: 1.使用rollup(也就是roll up累计的意思)操作产生s ...

  3. Oracle 高级排序函数 和 高级分组函数

    高级排序函数: [ ROW_NUMBER()| RANK() | DENSE_RANK ] OVER (partition by xx order by xx) 1.row_number() 连续且递 ...

  4. [转帖]万字详解Oracle架构、原理、进程,学会世间再无复杂架构

    万字详解Oracle架构.原理.进程,学会世间再无复杂架构 http://www.itpub.net/2019/04/24/1694/ 里面的图特别好 数据和云 2019-04-24 09:11:59 ...

  5. [转帖]详解oracle数据库唯一主键SYS_GUID()

    详解oracle数据库唯一主键SYS_GUID() https://www.toutiao.com/i6728736163407856139/ 其实 需要注意 这里满不能截取 因为截取了 就不一定唯一 ...

  6. SQL 中详解round(),floor(),ceiling()函数的用法和区别?

    SQL 中详解round(),floor(),ceiling()函数的用法和区别? 原创 2013年06月09日 14:00:21   摘自:http://blog.csdn.net/yueliang ...

  7. ​ 用一个开发案例详解Oracle临时表

    ​ 用一个开发案例详解Oracle临时表 2016-11-14 bisal ITPUB  一.开发需求  最近有一个开发需求,大致需要先使用主表,或主表和几张子表关联查询出ID(主键)及一些主表字段 ...

  8. 详解Oracle手动创建数据库几大步骤

    在这里我们将介绍Oracle手动创建数据库几大步骤,包括前期的准备工作,以及具体的实施. Oracle手动创建数据库是本文介绍的重点,希望通过本文能帮助大家更好的利用Oracle.51CTO也向您推荐 ...

  9. [转帖]【Oracle】详解Oracle中NLS_LANG变量的使用

    [Oracle]详解Oracle中NLS_LANG变量的使用 https://www.cnblogs.com/HDK2016/p/6880560.html NLS_LANG=LANGUAGE_TERR ...

随机推荐

  1. Mac Apache Tomcat 配置

    1.配置准备工作 1)配置 Tomcat 准备工作 下载相关软件 apache-tomcat-9.0.6.zip tomcat 官网 Tomcat 配置软件下载地址,密码:sgrn. 2)配置注意事项 ...

  2. springboot 多环境配置yml或properties

    https://www.cnblogs.com/mr-yang-localhost/p/8971327.html   springboot 多环境配置 https://blog.csdn.net/li ...

  3. Android开发中的神坑和知识点记录

    1.SDK Manager.exe闪退的问题 http://blog.csdn.net/fambit025/article/details/26984345 1.找到android.bat,在源码处找 ...

  4. EndNote 输出样式模板(根据国家标准制订)

    EndNote 输出样式模板(根据国家标准制定)   EndNote 相当于一个数据库,将添加/导入的文献存档.需要引用文献的时候就从中选择一个插入到文档中,EndNote 会自动给你编号.在文档末尾 ...

  5. 网页端,JSON导成CSV文件

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. 《AndroidStudio每日一贴》2.高速查看项目中近期的变更

    <AndroidStudio每日一贴>2.高速查看项目中近期的变更 高速查看项目中近期的变更,使用快捷键: option + shift +c 很多其它有用技巧请查看<Android ...

  7. ssr.js数据模拟工具

    ssr相当于是搭建了一个 Mock Server ,构建假数据,然后把这些假数据存到 JSON 文件上,Mock Server 可以响应请求或者生成页面,当然也可以顺便生成 API 文档. 强制跨域访 ...

  8. 菜鸟调错(四)——Spring与DWR集成,配置文件报错

    背景简介: 该项目是市信用办的一个系统,之前好像是一个石家庄的公司负责的.我属于是半路接手.拿到源码后,根据他们给的简(shao)单(de)明(ke)了(lian)的说明把项目搭起来.结果可想而知,项 ...

  9. spark读取hdfs数据本地性异常【转】

    在分布式计算中,为了提高计算速度,数据本地性是其中重要的一环. 不过有时候它同样也会带来一些问题. 一.问题描述 在分布式计算中,大多数情况下要做到移动计算而非移动数据,所以数据本地性尤其重要,因此我 ...

  10. 【教程】linux下安装Google Chrome

    google chrome       google浏览器一直都是深受大家喜爱的一个浏览器,而且其跨平台性比较好,这对于书签同步来说是非常重要的.但是在linux下,默认的是火弧浏览器,而google ...