GROUP BY中ROLLUP/CUBE/GROUPING/GROUPING SETS使用示例
oracle group by中rollup和cube的区别:
Oracle的GROUP BY语句除了最基本的语法外,还支持ROLLUP和CUBE语句。CUBE ROLLUP 是用于统计数据的。
实验使用SCOTT用户的EMP表测试
1.仅使用GROUP BY分组,GROUP BY后的单列可以用括号,也可以不用。以下两种写法作用一样:
SCOTT@bys1>SELECT deptno, avg(sal) FROM emp GROUP BY deptno;
SCOTT@bys1>SELECT deptno, avg(sal) FROM emp GROUP BY (deptno);
DEPTNO AVG(SAL)
---------- ----------
30 1566.66667
20 2175
10 2916.66667
正常分组,GROUP BY后的多个列之前要用逗号隔开,列名可以写到 括号里,也可以不使用括号。
下面三种写法作用一样:
SCOTT@bys1>SELECT nvl(to_char(deptno),'heji') ,job, avg(sal) FROM emp GROUP BY (job,deptno);
SCOTT@bys1>SELECT deptno,job, avg(sal) FROM emp GROUP BY (job,deptno);
SCOTT@bys1>SELECT deptno,job, avg(sal) FROM emp GROUP BY job,deptno;
DEPTNO JOB AVG(SAL)
---------- --------- ----------
20 MANAGER 2975
10 PRESIDENT 5000
10 CLERK 1300
30 SALESMAN 1400
20 ANALYST 3000
30 MANAGER 2850
10 MANAGER 2450
30 CLERK 950
20 CLERK 950
##################################################################################
2.在GROUP BY语句中使用ROLLUP:
使用ROLLUP操作符时,在生成原有统计结果基础上,生成横向小计结果。
为每个分组返回一条小计记录,并为全部分组返回总计。
下面两个语句只用到了一个分组列,所以返回的是一个总计。
SCOTT@bys1>SELECT deptno, avg(sal) FROM emp GROUP BY rollup(deptno);
DEPTNO AVG(SAL)
---------- ----------
10 2916.66667
20 2175
30 1566.66667
2073.21429
使用NVL,如果deptno列为NULL,则用'heji'。可以使结果更美观。
SCOTT@bys1>SELECT nvl(to_char(deptno),'heji') as deptno, avg(sal) FROM emp GROUP BY rollup(deptno);
DEPTNO AVG(SAL)
---------------------------------------- ----------
10 2916.66667
20 2175
30 1566.66667
heji 2073.21429
下面语句用到了两个列。
可以看到下面查询产生了如下结果行:
-----它按照grouping list列从右到左进行更高层的聚合
1.对(deptno,job)进行GROUP BY,即按部门分组,相同部门里再按相同岗位进行分组。聚合统计同一部门相同岗位的平均工资。
2.对分组后的(deptno)进行GROUP BY,即相同部门的分组聚合统计。这里就是统计同一部门所有人的平均工资
3.对所有员工的平均工资聚合统计
这里如果是GROUP BY rollup(a,b,c);对(a,b,c)三列分组的话,就是先对(a,b,c)进行GROUP BY,再对(a,b)进行GROUP BY,再对(a)进行GROUP BY,再对全表GROUP BY。
即ROLLUP(1,2,N)时,GROUP BY的所有可能的GROUP BY数是2+N个,比如CUBE(a,b,c);时,总共有4个。
SCOTT@bys1>SELECT nvl(to_char(deptno),'heji') as deptno,job,avg(sal) FROM emp GROUP BY rollup(deptno,job);
DEPTNO JOB AVG(SAL)
---------------------------------------- --------- ----------
10 CLERK 1300
10 MANAGER 2450
10 PRESIDENT 5000
10 2916.66667
20 CLERK 950
20 ANALYST 3000
20 MANAGER 2975
20 2175
30 CLERK 950
30 MANAGER 2850
30 SALESMAN 1400
30 1566.66667
heji 2073.21429
########################################################################################################
3.在GROUP BY中使用CUBE:
使用CUBE操作符时,在生成原有统计结果基础上,生成纵向小计结果。
返回所有列组合的小计信息,同时在最后显示总计信息
下面两个语句只用到了一个分组列,所以返回的是一个总计。--ROLLUP总计在下面,CUBE的统计结果在上面。
SCOTT@bys1>SELECT nvl(to_char(deptno),'zongji'), avg(sal) FROM emp GROUP BY cube(deptno);
NVL(TO_CHAR(DEPTNO),'ZONGJI') AVG(SAL)
---------------------------------------- ----------
zongji 2073.21429
10 2916.66667
20 2175
30 1566.66667
下面语句用到了两个列。
可以看到下面查询产生了如下结果行:
1.是对(deptno,job)进行GROUP BY,即按部门、同一部门相同岗位GROUP BY。统计了同一部门相同岗位的平均工资及同一部门所有岗位的平均工资。
2.又对每个(job)进行GROUP BY,即不管部门,对表中所有行按JOB列进行GROUP BY。统计了各个岗位的平均工资
3.最后统计了所有员工的平均工资。即统计的第2步分组后的各种岗位的平均工资--也可能是全部员工的工资平均。
如果是GROUP BY CUBE(a,b,c);首先会对(A、B、C)进行GROUP BY,然后依次是(A、B),(A、C),(A),(B、C),(B),(C),再对全表进行GROUP BY。
即CUBE(1,2,N)时,GROUP BY的所有可能的GROUP BY数是2的N次方,比如CUBE(a,b,c);时,总共有8个。
SCOTT@bys1>SELECT nvl(to_char(deptno),'zongji') as deptno,job,avg(sal) FROM emp GROUP BY cube(deptno,job);
DEPTNO JOB AVG(SAL)
---------------------------------------- --------- ----------
zongji 2073.21429
zongji CLERK 1037.5
zongji ANALYST 3000
zongji MANAGER 2758.33333
zongji SALESMAN 1400
zongji PRESIDENT 5000
10 2916.66667
10 CLERK 1300
10 MANAGER 2450
10 PRESIDENT 5000
20 2175
20 CLERK 950
20 ANALYST 3000
20 MANAGER 2975
30 1566.66667
30 CLERK 950
30 MANAGER 2850
30 SALESMAN 1400
实验总结:ROLLUP非常高效,对一个查询增加的开销非常少;CUBE相对更耗费资源。
在GROUP BY子句有列(a,b)两列时,ROLLUP统计(a,b),(a);而CUBE统计了(a,b),(a),(b)。
在此实验中就是:
ROLLUP统计了按(deptno,job)分组汇总,按(deptno)分组汇总,最后对全表进行GROUP BY操作。
CUBE统计了按(deptno,job)分组汇总,按(deptno)分组汇总,按(job)分组汇总,最后对全表进行GROUP BY操作。
#############################################################################################
4.grouping函数,解决在返会的结果中如何能准确区分出那些是小计,哪些是汇总数据。GROUPING只能在使用ROLLUP或CUBE的查询中使用。
对输入列返回0或1,如果该行数据使用了数据的列中的信息,即此列数据参与ROLLUP/CUBE函数分组汇总活动,则输出0;没有用到则输出1
或者说,对于该行得出的统计数据,需要从输入列中选择数据的话,输出0;不需要选择数据的就输出1
如下:GROUP BY rollup(deptno,job)时,可以看到在不同聚合统计列deptno,job字段的使用情况。0使用该字段,1未使用。
SCOTT@bys1>SELECT nvl(to_char(deptno),'zongji') as deptno,job,avg(sal),grouping(deptno),grouping(job) FROM emp GROUP BY rollup(deptno,job);
DEPTNO JOB AVG(SAL) GROUPING(DEPTNO) GROUPING(JOB)
---------------------------------------- --------- ---------- ---------------- -------------
10 CLERK 1300 0 0
10 MANAGER 2450 0 0
10 PRESIDENT 5000 0 0
10 2916.66667 0 1
20 CLERK 950 0 0
20 ANALYST 3000 0 0
20 MANAGER 2975 0 0
20 2175 0 1
30 CLERK 950 0 0
30 MANAGER 2850 0 0
30 SALESMAN 1400 0 0
30 1566.66667 0 1
zongji 2073.21429 1 1
如下:GROUP BY cube(deptno,job)时,可以看到在不同聚合统计列deptno,job字段的使用情况。0使用该字段,1未使用。
SCOTT@bys1>SELECT nvl(to_char(deptno),'zongji') as deptno,job,avg(sal),grouping(deptno),grouping(job) FROM emp GROUP BY cube(deptno,job);
DEPTNO JOB AVG(SAL) GROUPING(DEPTNO) GROUPING(JOB)
---------------------------------------- --------- ---------- ---------------- -------------
zongji 2073.21429 1 1
zongji CLERK 1037.5 1 0
zongji ANALYST 3000 1 0
zongji MANAGER 2758.33333 1 0
zongji SALESMAN 1400 1 0
zongji PRESIDENT 5000 1 0
10 2916.66667 0 1
10 CLERK 1300 0 0
10 MANAGER 2450 0 0
10 PRESIDENT 5000 0 0
20 2175 0 1
20 CLERK 950 0 0
20 ANALYST 3000 0 0
20 MANAGER 2975 0 0
30 1566.66667 0 1
30 CLERK 950 0 0
30 MANAGER 2850 0 0
30 SALESMAN 1400 0 0
5.grouping SETS函数
只返回统计信息,就是上一个查询中提出两个 GROUPING 的两个列全为0或全为1的都过滤掉。
SCOTT@bys1>SELECT nvl(to_char(deptno),'zongji') as deptno,job,avg(sal),grouping(deptno),grouping(job) FROM emp GROUP BY grouping sets(deptno,job);
DEPTNO JOB AVG(SAL) GROUPING(DEPTNO) GROUPING(JOB)
---------------------------------------- --------- ---------- ---------------- -------------
zongji CLERK 1037.5 1 0
zongji SALESMAN 1400 1 0
zongji PRESIDENT 5000 1 0
zongji MANAGER 2758.33333 1 0
zongji ANALYST 3000 1 0
30 1566.66667 0 1
20 2175 0 1
10 2916.66667 0 1
不过当查询只有一个聚合列时,是将全表统计的给过滤了:
SCOTT@bys1>SELECT deptno, avg(sal),grouping(deptno) FROM emp GROUP BY cube(deptno);
DEPTNO AVG(SAL) GROUPING(DEPTNO)
---------- ---------- ----------------
2073.21429 1
10 2916.66667 0
20 2175 0
30 1566.66667 0
SCOTT@bys1>SELECT deptno, avg(sal),grouping(deptno) FROM emp GROUP BY grouping sets(deptno);
DEPTNO AVG(SAL) GROUPING(DEPTNO)
---------- ---------- ----------------
30 1566.66667 0
20 2175 0
10 2916.66667 0
6.GROUPING_ID(column_name1,column_name2…)----这个没看懂,也没实验
这个返回一个整数,最小为0,这个整数怎么确定,将上面的输入的列,分配以bit,column_name1 的在column_name2的左边,
这样就形成了一个二进制数,将它转为10进制就是获得的数了,
怎么确定每位的0和1?
每位的值,和 GROUPING(column_name)的值是一样的,
例如上面的GROUPING(column_name1) GROUPING(column_name2) 为1 和0
则获得的值为 0b10 ,即2.
GROUP BY中ROLLUP/CUBE/GROUPING/GROUPING SETS使用示例的更多相关文章
- Oracle的rollup、cube、grouping sets函数
转载自:https://blog.csdn.net/huang_xw/article/details/6402396 Oracle的group by除了基本用法以外,还有3种扩展用法,分别是rollu ...
- oracle group by中cube和rollup字句的使用方法及区别
oracle group by中rollup和cube的区别: Oracle的GROUP BY语句除了最基本的语法外,还支持ROLLUP和CUBE语句. 如果是ROLLUP(A, B, C)的话,先 ...
- Oracle中group by 的扩展函数rollup、cube、grouping sets
Oracle的group by除了基本使用方法以外,还有3种扩展使用方法,各自是rollup.cube.grouping sets.分别介绍例如以下: 1.rollup 对数据库表emp.如果当中两个 ...
- SQL GROUP BY GROUPING SETS,ROLLUP,CUBE(需求举例)
实现按照不同级别分组统计 关于GROUP BY 中的GROUPING SETS,ROLLUP,CUBE 从需求的角度理解会更加容易些. 需求举例: 假如一所学校只有两个系, 每个系有两个专业, 每个专 ...
- [Oracle] Group By 语句的扩展 - Rollup、Cube和Grouping Sets
常常写SQL语句的人应该知道Group by语句的主要使用方法是进行分类汇总,以下是一种它最常见的使用方法(依据部门.职位分别统计业绩): SELECT a.dname,b.job,SUM(b.sal ...
- SQL Server2008 程序设计 汇总 GROUP BY,WITH ROLLUP,WITH CUBE,GROUPING SETS(..)
--SQL Server2008 程序设计 汇总 GROUP BY ,WITH ROLLUP WITH CUBE GROUPING SET(..) /*********************** ...
- SQLSERVER中的ALL、PERCENT、CUBE关键字、ROLLUP关键字和GROUPING函数
SQLSERVER中的ALL.PERCENT.CUBE关键字.ROLLUP关键字和GROUPING函数 先来创建一个测试表 USE [tempdb] GO )) GO INSERT INTO [#te ...
- [转]详解Oracle高级分组函数(ROLLUP, CUBE, GROUPING SETS)
原文地址:http://blog.csdn.net/u014558001/article/details/42387929 本文主要讲解 ROLLUP, CUBE, GROUPING SETS的主要用 ...
- 解析数仓OLAP函数:ROLLUP、CUBE、GROUPING SETS
摘要:GaussDB(DWS) ROLLUP,CUBE,GROUPING SETS等OLAP函数的原理解析. 本文分享自华为云社区<GaussDB(DWS) OLAP函数浅析>,作者: D ...
随机推荐
- Linux云服务器下Redis安装与部署以及设置redis后台运行
Redis下载: http://redis.io/download 我下载的4.0.11 上传到服务器 注: 官方的建议是直接在linux下载并解压编译 这里不建议先解压再上传到服务器,之前我这样做, ...
- ApiPost自动化测试基础之:接口参数依赖的情景处理
在<ApiPost环境变量之第1课>里,我们介绍了什么是ApiPost环境变量,并如何定义.使用它. 环境变量.接口参数依赖的处理是ApiPost自动化测试的基础.本文主要讲解接口参数依赖 ...
- android 启动 service 的两种方式,及什么时候用哪个 android 什么时候用bindService
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha android 什么时候用bindService ============ 启动方式有 ...
- C语言应用操作之文件
文件是C语言中德中的重点,小编在学习C语言基础知识的时候,大多数的输入输出操作是在屏幕上进行的,现在总算在文件学习上感觉到高大上的样纸.在以前数据量很小时,我们通常将信息从键盘在屏幕上进行输入输出的, ...
- 8.4 正睿暑期集训营 Day1
目录 2018.8.4 正睿暑期集训营 Day1 A 数对子 B 逆序对 C 盖房子 考试代码 A B C 2018.8.4 正睿暑期集训营 Day1 时间:4.5h(实际) 期望得分:30+50+3 ...
- Slickflow.NET 开源工作流引擎高级开发(三) -- 并行分支容器与会签工作流模式的组合
前言: 流程引擎的核心功能是负责解析流程定义XML和流转,业务环节的不断积累,让人们不断总结和抽象出一些模式,这些模式统称为工作流模式(Workflow Pattern).本文的重点就是介绍一种常见 ...
- MikroTik RouterOS使用VirtualBox挂载物理硬盘作为虚拟机硬盘进行安装
说明:这一切似乎在Windows下更好操作.虚拟机操作不是难点,难点在于虚拟磁盘的转换挂载 一.先挂载硬盘 # 创建虚拟镜像并映射到物理硬盘 cd "c:\Program Files\Ora ...
- Nginx担当WebSockets代理
Nginx担当WebSockets代理 英文原文:http://nginx.com/blog/websocket-nginx/ 作者:chszs,转载需注明. 博客主页:http://blog.csd ...
- Android 开源库获取途径整理
介绍眼下收藏 Android 开源库比較多的 GitHub 项目.站点.Twitter.App 及怎样获取最新的 Android 开源库. 微信号: 1. GitHub Android 开源项目汇总 ...
- IEnumerable是集合,IEnumerator是集合的迭代器
我们常用IEnumerable,却忽视IEnumerator.简单来说,IEnumerable是可以被循环遍历的集合,IEnumerator实施循环遍历. 接口分别是: public interfac ...