Oracle的group by除了基本用法以外,还有3种扩展用法,分别是rollup、cube、grouping

sets。

1 rollup

假设有一个表test,有A、B、C、D、E5列。

如果使用group by rollup(A,B,C),首先会对(A、B、C)进行GROUP BY,然后对(A、B)进行GROUP

BY,然后是(A)进行GROUP BY,最后对全表进行GROUP BY操作。roll

up的意思是“卷起”,这也可以帮助我们理解group by

rollup就是对选择的列从右到左以一次少一列的方式进行grouping直到所有列都去掉后的grouping(也就是全表grouping),对于n个参数的rollup,有n+1次的grouping。以下2个sql的结果集是一样的:

Select A,B,C,sum(E) from test group by rollup(A,B,C)

Select A,B,C,sum(E) from test group by A,B,C

union all

Select A,B,null,sum(E) from test group by A,B

union all

Select A,null,null,sum(E) from test group by A

union all

Select null,null,null,sum(E) from test

2 cube

cube的意思是立方,对cube的每个参数,都可以理解为取值为参与grouping和不参与grouping两个值的一个维度,然后所有维度取值组合的集合就是grouping的集合,对于n个参数的cube,有2^n次的grouping。如果使用group

by cube(A,B,C),,则首先会对(A、B、C)进行GROUP

BY,然后依次是(A、B),(A、C),(A),(B、C),(B),(C),最后对全表进行GROUP

BY操作,一共是2^3=8次grouping。同rollup一样,也可以用基本的group by加上结果集的union

all写出一个与group by cube结果集相同的sql:

Select A,B,C,sum(E) from test group by cube(A,B,C);

Select A,B,C,sum(E) from test group by A,B,C

union all

Select A,B,null,sum(E) from test group by A,B

union all

Select A,null,C,sum(E) from test group by A,C

union all

Select A,null,null,sum(E) from test group by A

union all

Select null,B,C,sum(E) from test group by B,C

union all

Select null,B,null,sum(E) from test group by B

union all

Select null,null,C,sum(E) from test group by C

union all

Select null,null,null,sum(E) from test;

3 grouping sets

grouping sets就是对参数中的每个参数做grouping,也就是有几个参数做几次grouping,例如使用group

by grouping sets(A,B,C),则对(A),(B),(C)进行group by,如果使用group by

grouping sets((A,B),C),则对(A,B),(C)进行group by。甚至grouping by grouping

set(A,A)都是语法允许的,也就是对(A)进行2次group by,grouping sets的参数允许重复

4 总结

rollup (N+1个分组方案)

cube (2^N个分组方案)

grouping sets (自定义罗列出分组方案)

5 注意点

5.1 机制不同

在rollup和cube的说明中分别给出了用基本group by加结果集union

all给出了结果集相同的sql,但这只是为了理解的方便而给出的sql,并不说明rollup和cube与基本group

by加结果集union

all等价。实际上两者的内部机制是安全不一样的,前者除了写法简洁以外,运行时不需多次扫描表,效率远比后者高。

5.2 集合可运算

3种扩展用法的参数可以是源表中的某一个具体的列,也可以是若干列经过计算而形成的一个新列(比如说A+B,A||B),也可以是这两种列的一个集合(例如(A+B,C)),对于grouping

set更是特殊,可以是空集合(),表示对全表进行group by。

5.3 group by 与 rollup, cube组合使用

3)Group by的基本用法以及这3种扩展用法可以组合使用,也就是说可以出现group by

A,rollup(A,B)这样的用法,oracle将对出现在group

by中的每种用法的grouping列集合做笛卡尔积然后对其中的每一个元素做group by。这话说起来挺绕口,举例说明吧,group

by A,

rollup(A,B),基本用法的grouping集合是(A),rollup(A,B)的grouping集合是((A,B),(A),()),两个集合的笛卡尔积集合是((A,A,B),(A,A),(A)),所以会首先对(A,A,B)做group

by,然后对(A,A)做group by,最后对(A)做group by。实际上对(A,A,B)做group

by和对(A,B)做group by两者是完全等价的(group by A,A,B结果和group by

A,B完全一样),同理对(A,A)做group by和对(A)做group

by也是等价的。简化后的结果就是首先对(A,B)做group by,然后对(A)做group by,最后再对(A)做group

by。下面给出两个等价的sql以便理解:

Select A,B,sum(E) from test1 group by A, rollup(A,B);

Select A,B,sum(E) from test1 group by A,B

Union all

Select A,null,sum(E) from test1 group by A

Union all

Select A,null,sum(E) from test1 group by A;

6 grouping()、grouping_id()、group_id()

6.1 grouping()

参数只有一个,而且必须为group

by中出现的某一列,表示结果集的一行是否对该列做了grouping。对于对该列做了grouping的行而言,grouping()=0,反之为1;

6.2 grouping_id()

参数可以是多个,但必须为group

by中出现的列。Grouping_id()的返回值其实就是参数中的每列的grouping()值的二进制向量,例如如果grouping(A)=1,grouping(B)=0,则grouping_id(A,B)的返回值就是二进制的10,转成10进制就是2。

6.3 group_id()

无参数。见上面的说明3),group

by对某些列的集合会进行重复的grouping,而实际上绝大多数情况下对结果集中的这些重复行是不需要的,那就必须有办法剔出这些重复grouping的行。当结果集中有n条重复grouping而形成的行时,每行的group_id()分别是0,1,…,n,这样我们在条件中加入一个group_id()<1就可以剔出这些重复grouping的行了。

7 示例

7.1 建表与数据

SQL> create table test(department_id

number, a varchar2(20), b varchar2(20));

Table created

SQL> insert into test values(10,

'A', 'B');

1 row inserted

SQL> commit;

Commit complete

7.2 查询语句

select department_id,

a,

b,

grouping(department_id),

grouping(a),

grouping(b)

from test

group by rollup(department_id, a,

b)

order by 4, 5, 6;

select department_id,

a,

b,

grouping(department_id),

grouping(a),

grouping(b)

from test

group by cube(department_id, a,

b)

order by 4, 5, 6;

Grouping函数:

可以接受一列,返回0或1。如果列值为空,则返回1,非空则返回0。它只能在rollup和或cube函数中使用,因为在统计中显示“全部”的那一项统计值时,那一项的标签通常是空的,这时grouping就非常有用,还可以在grouping的基础上进行decode,

case等进行美化。

SQL> select grouping(index_type)

g_ind, grouping(status) g_st, index_type, status, count(*)

2 from t group by

rollup(index_type, status) order by 1, 2;

G_IND G_ST

INDEX_TYPE STATUS COUNT(*)

---------- ---------- --------------------------- --------

----------

0 0

LOB N/A 1

0 0

LOB VALID 572

0 0 FUNCTION-BASED

NORMAL VALID 17

0 0 FUNCTION-BASED

DOMAIN VALID 1

0 0 IOT -

TOP VALID

oracle中的roll up,oracle  group by 与roll up,cube,grouping sets,grouping_id联合使用相关推荐

  1. oracle中的guid,在Oracle中使用Guid

    在Oracle中使用Guid 在Oracle中使用Guid 在Oracle中可以用SYS_GUID()来生成一个guid,相当于msSql中的newid(). 在Oracle9i和Oracle 10g ...

  2. oracle数据库insert into,oracle中insert into用法 oracle中insert如何带条件添加数据?

    oracle insert into 脚本怎么写 INSE INTO BOOK(bookid,name,price) VALUES('100123','oracle ',54); 或者 INSE IN ...

  3. [转]详解Oracle高级分组函数(ROLLUP, CUBE, GROUPING SETS)

    原文地址:http://blog.csdn.net/u014558001/article/details/42387929 本文主要讲解 ROLLUP, CUBE, GROUPING SETS的主要用 ...

  4. oracle中asm磁盘不足,Oracle用户无法访问ASM磁盘组问题

    1. 权限问题引起找不到ASM磁盘组 1.1 确认操作系统用户属主 # 确认属主 Grid Infrastructure Home Owner : grid Primary Group : oinst ...

  5. oracle中col 的用法,Oracle中的SUM用法讲解,

    Oracle中的SUM用法讲解, Oracle中的SUM条件查询 1.按照区域编码分组查询区域编码.IPTV_NBR不为空的数量.ACC_NBR不为空的数量.所有用户数量 SELECT AREA_CO ...

  6. oracle中的循环函数,Oracle日期函数和循环总结

    一,日期相关的函数 Select to_char(sysdate,'Q') from dual;--指定日期的季度 Select to_char(sysdate,'MM') from dual;--月 ...

  7. oracle中存在函数吗,Oracle中的函数

    Oracle中的函数 1.单行函数也称标量函数,对于从表中查询的每一行,该函数都返回一个值.单行函数可用与select子句中,也可用于where子句中.单行函数大致分为: >.日期函数 > ...

  8. 查询oracle中用户的角色,oracle中用户角色的查询和授权

    用户拥有的系统权限 select  privilege  from dba_sys_privs  where grantee='&USERNAME' union select  privile ...

  9. oracle中的输入 amp,Oracle之SQL学习

    1.Oracle 更改会话(更改oracle中显示日期的方式) SQL> alter session set NLS_date_format='YYYY-MM-DD'; 2.使用绑定变量来输入记 ...

最新文章

  1. Ext JS学习第十六天 事件机制event(一)
  2. cf13C Sequence(DP)
  3. 博士考试考完了,庆祝一下
  4. [Linux] BASH程序设计
  5. 2016年大数据Spark“蘑菇云”行动之spark streaming消费flume采集的kafka数据Directf方式...
  6. hbase由于一台regionserver和datanode挂死导致hlog split问题
  7. 121道分布式面试题和答案,25K妥妥的
  8. 我国会计界计算机软件界大规模研究,初级会计电算化第一章练习.doc
  9. 【100个 Unity小知识点】☀️ | Unity 可以在编辑器中读取Excel,打包成exe后就无法读取的问题
  10. iOS GPS定位减小精度误差的几种处理方法
  11. linux服务器开机管理,中标麒麟Linux服务器操作系统启动管理(29页)-原创力文档...
  12. Python ORM框架peewee
  13. Apache POI 设置Excel单元格的宽度和高度
  14. win10 GTX1050配置VS19+CUDA10.2+CUDNN
  15. BUUCTF [GYCTF2020] Blacklist
  16. Java夜未眠.程序员的心声
  17. jsp教学网站百度文库_精品课程JSP教学网站的评价研究
  18. 神经网络初认识——BP神经网络(7月18,再次认识)
  19. es6中的generator函数详解
  20. 【django学习】——Django介绍和实战(开发简易版博客网页)

热门文章

  1. 联想台式计算机内存哪个好,联想台式机哪款好 联想台式机家悦3000评测【详解】...
  2. 如何在微信小程序中集成认证服务—邮箱地址篇
  3. python 量子计算包_ProjectQ:解锁Python实现量子计算的新方式!
  4. 传“谷歌金山词霸”将于近日正式推出
  5. 用好Linux备份软件
  6. DEV ASPXGRIDVIEW控件中的Findcontrol
  7. 软件测试(基础知识)
  8. 阅读书源最新2020在线导入_推荐3款无广告、速度快、可换源的小说利器,5星使用阅读体验...
  9. 2021世界燕窝滋补品上海展带您揭晓一碗燕窝的营养与价格!
  10. CISP、CISP-PTE、CISP-DSG、CISP-IRE报名条件、考试内容、考题结构