Oracle的rollup、cube、grouping sets函数

Group by、rollup、cube、grouping sets区别

oracle除了group by基本用法之外,还有ROLLUP,CUBE,GROUPING SETS 等扩展方法,这些可以理解为Group By 分组函数封装后的精简用法,相当于多个union all 的组合显示效果,但是要比 多个 union all 的效率要高。

1.测试数据

1CREATE TABLE emp ( 2 ID NUMBER PRIMARY KEY, 3 NAME NVARCHAR2(30), 4 sex VARCHAR2(10), 5 birthday DATE, 6 work_location VARCHAR2(30), 7 sal NUMBER(10) 8); 9COMMENT ON TABLE emp IS '员工信息表'; 10COMMENT ON COLUMN emp.id IS '员工id'; 11COMMENT ON COLUMN emp.name IS '员工姓名'; 12COMMENT ON COLUMN emp.sex IS '性别'; 13COMMENT ON COLUMN emp.birthday IS '出生日期'; 14COMMENT ON COLUMN emp.work_location IS '工作地点'; 15COMMENT ON COLUMN emp.sal IS '工资'; 16 17INSERT INTO emp(ID, NAME, sex, birthday, work_location, sal) 18VALUES(1, '小王','男', to_date('1994-12-08','yyyy-mm-dd'), '杭州', 4500); 19INSERT INTO emp(ID, NAME, sex, birthday, work_location, sal) 20VALUES(2, '小瑞','男', to_date('1995-02-01','yyyy-mm-dd'), '杭州', 8000); 21INSERT INTO emp(ID, NAME, sex, birthday, work_location, sal) 22VALUES(3, '小倩子','女', to_date('1994-07-08','yyyy-mm-dd'), '上海', 6000); 23INSERT INTO emp(ID, NAME, sex, birthday, work_location, sal) 24VALUES(4, '小权','男', to_date('1993-01-01','yyyy-mm-dd'), '北京', 8000); 25INSERT INTO emp(ID, NAME, sex, birthday, work_location, sal) 26VALUES(5, '小优子','男', to_date('1994-12-08','yyyy-mm-dd'), '深圳', 9000); 27INSERT INTO emp(ID, NAME, sex, birthday, work_location, sal) 28VALUES(6, '小游子','女', to_date('1994-07-08','yyyy-mm-dd'), '深圳', 7500);

2.group by

  • GROUP BY语法可以根据给定数据列的每个成员对查询结果进行分组统计,最终得到一个分组汇总表。

  • select子句中的列名必须为分组列或聚合函数,聚合函数对于group by子句定义的每个组返回一个结果。

  • 只能 select 聚合函数(如:sum() 、max()、min()、avg()、count())

  • 对组筛选只能 having,不能是 where(where执行在分组之前,所以where中不能出现聚合函数)

  • 不能对 clob 类型项目进行 group by

    WITH t_1 AS ( #with子查询 SELECT to_clob(t.name) a#to_clob函数,将普通字段转换为clob类型 FROM emp t ) #以下的SQL报错 SELECT COUNT(1) FROM t_1 GROUP BY a;#a为clob类型的字段,不能应用于group by进行分组

3.rollup

  • 从右到左递减分组
  • 先小计在合计
  • 按照order by 1(,2,3,4...)排序
  • 如果rollup参数为N各,则相当于N+1个group by 分组的union的结合

例如:group by rollup(A,B,C),则执行的结果为首先对A,B,C进行group by分组,之后A,B分组,之后A分组,最后对null,也就是整个表进行group by

1SELECT A, B, C, SUMDFROM table_name GROUP BY ROLLUP(A, B, C)2等同于 3SELECT * from ( 4SELECT A, B, C, SUMDFROM table_name GROUP BYA, B, C5UNION ALL 6SELECT A, B, null, SUMDFROM table_name GROUP BY(A, B, null) 7UNION ALL 8SELECT A, null, null, SUMDFROM table_name GROUP BY (A, null, null) 9UNION ALL 10SELECT null, null, null, SUMDFrom table_name group by (null, null, null) 11) order by 1, 2, 3

 

4.CUBE

  •  cube为立方体的意思,实现交叉组合,结果没有顺序(rollup是有顺序的)
  • 如果cude参数为N个,会将group by执行2^N
  • 当cube一个参数时等同于rollup

它比 rollup 扩展更加精细,组合类型更多,对于 cube 来说,列的名字只要一样,那么顺序无所谓,结果都是一样的,例如rollup(A,B,C)和rollup(B,C,A)结果是一样的。因为 cube 是各种可能情况的组合,只不过统计的结果顺序不同而已。但是对于 rollup 来说,列的顺序不同,执行顺序从右开始递减,则结果不同。

例如:group by cube(A,B,C) ORDER BY A,B,C之后,group by执行的顺序为:(A,B,C),(A,B),(A,C),(A),(B,C),(B),(C),(null全部)。就等同于这些个group by的组合的union all

如果不order by则先执行null全部,之后C,最后A,B,C组合

5.GROUPING SETS

  • group by A,B是对A和B同时进行分组
  • group by grouping set(A,B)是对A,B单独进行分组

6.GROUPING

  • 用于区分 原有值 和 统计项,与group by搭配使用
  • 參数仅仅有一个,并且必须为group by中出现的某一列
  • grouping(A) = 0 : 数据库中本来的值
  • grouping (A)= 1 : 统计的结果

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

Oracle的rollup、cube、grouping sets函数 - HelloWorld