SQL里的group by分组统计功能很常见,可它的扩展用法多数人并不完全熟悉。本文将介绍group by的扩展用法:rollup、cube、grouping sets。
扩展用法不仅写法简洁,语句运行时不需要多次扫表,在数据库服务端执行也避免了应用层计算,效率极高。
大饼卷一切:rollup
test表有A、B、C、D、E共5列,使用group by rollup(A,B,C),首先对(A,B,C)进行group by,然后对(A,B)进行group by,接着对(A)进行group by,最后对全表进行group by。
参数列从右到左依次减少一列,再进行group by,对于n个参数,有n+1次group by。
select A,B,C,sum(E) from test group by rollup(A,B,C);
rollup写法可展开为如下的union all写法:
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;
光与暗的交织:cube
cube的每个参数可理解为取值参与分组和不参与分组中的一种形态,所有形态的集合就是cube分组的集合。
使用group by cube(A,B,C),首先会对(A,B,C)进行group by,然后依次是(A,B)、(A,C)、(A)、(B,C)、(B)、(C ),最后对全表进行group by。对于n个参数的cube,有2^n次group by。
select A,B,C,sum(E) from test group by cube(A,B,C);
cube写法可展开为如下的union all写法:
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;
专精组合:grouping sets
不如rollup和cube那么花里胡哨,grouping sets对每个参数进行group by,可自定义专属组合:
第三种group by grouping sets((A,B),())专精组合应用较广。
案例实践
创建测试表如下:
create table test(A varchar,B varchar,C varchar,D varchar,E int);
insert into test values('a1','b1','c1','d1',10);
insert into test values('a1','b1','c1','d2',20);
insert into test values('a2','b2','c2','d3',30);
insert into test values('a2','b2','c2','d4',50);
使用grouping sets分组
select A, (case when B is null then '合计:' else B || '[' || A || ']' end) sub, sum(E) totalfrom test group by grouping sets((A, B, C),())order by A;
执行结果如下:
a | sub | total ----+--------+------- a1 | b1[a1] | 30 a2 | b2[a2] | 80 | 合计: | 110 (3 rows)
当表数据为空时,PG与Oracle在rollup、cube、grouping sets的执行结果上有一点差异:Oracle会返回空行,PG会返回一行。
下面先清空表数据:
truncate table test;
再次执行上面的grouping sets语句,截图如下:
保持联系
本人组建了一个技术交流群:PG乐知乐享交流群。欢迎关注文章的小伙伴随缘加入,进群请加本人微信skypkmoon并备注PG乐知乐享。
编辑推荐:
- 报表统计之groupBy扩展用法03-14
- 系统快上线了,PostgreSQL压测的精髓全在这里03-14
- pg_rman类似于oracle的rman,够牛逼!!!03-14
- PG日常维护(一)03-14
- Postgresql日志参数配置03-14
- PG内存(连接)泄漏03-14
- PG与gdb core03-14
- PG基础:PG数据库创建03-14
相关推荐
-
雷神推出 MIX PRO II 迷你主机:基于 Ultra 200H,玻璃上盖 + ARGB 灯效
2 月 9 日消息,雷神 (THUNDEROBOT) 现已宣布推出基于英
-
制造商 Musnap 推出彩色墨水屏电纸书 Ocean C:支持手写笔、第三方安卓应用
2 月 10 日消息,制造商 Musnap 现已在海外推出一款 Oce
