Oracle group by 扩展函数详解(grouping sets、rollup、cube)

1 概述

1. 一般求和函数:聚合函数 |+ group by(1) 聚合函数: count(1)sum()avg()max()min() 

2. 高级分组函数:相当于多次 group by + union all,但效率更高 -- 若有 N 列
   (1) grouping sets:单独分组,group by N 次
   (2) rollup		:累计累加,group by N + 1 次,有默认排序
   (3) cube			:交叉列表,group by 2^N 次,无默认排序,rollup 的扩展

3. 扩展列
   (1) grouping     : 判断列值是否为空(0:非空,1:空)
   (2) grouping_id  :非空列合计,grouping 的扩展(二进制,注意顺序)
   (3) group_id()   :标识重复组(0:第一次分组,1:重复分区,无入参)

2 分组函数

基础数据准备:

-- 人员信息表
create table person_info (
   person_no     number(5),
   person_name   varchar2(30),
   sex           varchar2(3),
   money         number(8),
   work_location varchar2(10)
);

-- 测试数据
insert into person_info (person_no, person_name, sex, money, work_location)
values (1, '瑶瑶', '女', 100000, '深圳');

insert into person_info (person_no, person_name, sex, money, work_location)
values (2, '倩倩', '女', 200000, '深圳');

insert into person_info (person_no, person_name, sex, money, work_location)
values (3, '优优', '男', 300000, '深圳');

insert into person_info (person_no, person_name, sex, money, work_location)
values (4, '丽丽', '女', 200000, '武汉');

insert into person_info (person_no, person_name, sex, money, work_location)
values (5, '萌萌', '女', 100000, '武汉');
commit;

2.1 group by:一起分组(1)

1. group by:最基础的分组函数

2. 注意:不能对 'clob' 列分组 

例1:查询各地区的人数

select pi.work_location 地区, 
       count(1) 人数
  from person_info pi
 group by pi.work_location;

查询结果:

地区		人数
深圳		3
武汉		2

例2:不能对 clob 列分组(知晓即可,实际开发中,咱也不会这么操作)

-- 不能对 'clob' 类型项目进行 'group by'
with t_person_info as
 (select to_clob(pi.work_location) work_location_clob 
    from person_info pi)
select t.work_location_clob 地区,
       count(1) 人数
  from t_person_info t 
 group by t.work_location_clob;

查询结果:
在这里插入图片描述

2.2 grouping sets:单独分组(N)

1. group by (a, b)
   (1) 对 a, b '一起' 进行分组

2. group by grouping sets(a, b)
   (1) 对 a, b '单独' 进行分组
   (2) 等同于:
	   group by a
	   union all
	   group by b

测试截图:
在这里插入图片描述

等效 sql :

select pi.work_location 地区,  
       '' 性别,
       count(1) 人数
  from person_info pi
 group by pi.work_location
 
 union all
select '' 地区,  
       pi.sex 性别,
       count(1) 人数
  from person_info pi
 group by pi.sex;

2.3 rollup:累计累加(N + 1)

1. group by rollup(a, b)
   (1) 首先对 'a, b' 一起 group by
   (2) 然后对 'a' group by
   (3) 最后计算 '聚合函数'

2. 若有 N 列,则 group by N + 1 次(1group by null, null, 聚合函数)

3. 有默认排序:order by a, b 

测试截图:
在这里插入图片描述

等效 sql:

select * from (
  select a, b, null, count(1) from table_name group by(a, b, null)
  union all
  select a, null, null, count(1) from table_name group by (a, null, null)
  union all
  select null, null, null, count(1) from table_name group by (null, null, null)
) order by a, b

2.4 cube:交叉列表(2^N)

1. group by cube(a, b)
   (1) 首先对 'a, b' 一起 group by
   (2) 然后对 'a' group by 
   (3) 然后对 'b' group by -- 比 rollup 多此一项
   (4) 最后计算 '聚合函数'

2. cube 是 rollup 的扩展,组合类型更多
   若有 N 列,则 group by 2^N 次
   
3. 没有默认排序,这点和 rollup 不同
   (1) cube  : 只要列名一样,顺序无所谓,结果是都一样的
   (2) rollup: 列的顺序不同,结果不同

测试截图:
在这里插入图片描述

3 扩展列

3.1 grouping:列是否为空

1. 作用:'判断列值是否为空'
   (1) grouping = 0 => '非空'
   (2) grouping = 1 => '空'

2. 常用 grouping set, cube, rollup 一起使用

测试截图:
在这里插入图片描述

3.2 grouping_id:非空列合计

1. grouping_id 是 grouping 的扩展
   (1) grouping   : 区分列是否为空
   (2) grouping_id: 区分 grouping 列 '合计'(注意顺序)

2. 返回的 '二进制数',显示的是 '十进制数'
   (1) 1 + 1 = 112进制) = 310进制)
   (2) 1 + 0 = 102进制) = 210进制)

测试截图:
在这里插入图片描述

3.3 group_id:标识重复组

1. group_id(): 标识重复组(执行多次)
   (1) 无参数
   (2) 若返回值为 0:第一次分组
       若返回值为 1:重复分组

测试截图:
在这里插入图片描述

  • 18
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鱼丸丶粗面

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值