对GROUP BY的增强
创始人
2024-01-31 06:09:28
0
  • 使用ROLLUP操作产生求和值
  • 使用CUBE操作产生
  • 使用GROUPING函数确定该行值是由ROLLUP或者CUBE创建的
  • 使用GROUPING SETS生成一个简单的结果集

[oracle@oracle-db-19c ~]$ 
[oracle@oracle-db-19c ~]$ sqlplus / as sysdbaSQL*Plus: Release 19.0.0.0.0 - Production on Fri Nov 18 10:19:05 2022
Version 19.3.0.0.0Copyright (c) 1982, 2019, Oracle.  All rights reserved.Connected to:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0SQL> 
SQL> alter session set container=PDB1;Session altered.
SQL> show con_nameCON_NAME
------------------------------
PDB1
SQL> 
SQL> 
SQL> conn scott/tiger@PDB1
Connected.
SQL> 
SQL> show user
USER is "SCOTT"
SQL> 
SQL> 
SQL> set pagesize 200
SQL> set linesize 200
SQL> select * from emp;EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO
---------- ---------- --------- ---------- --------- ---------- ---------- ----------7369 SMITH      CLERK           7902 17-DEC-80        800                    207499 ALLEN      SALESMAN        7698 20-FEB-81       1600        300         307521 WARD       SALESMAN        7698 22-FEB-81       1250        500         307566 JONES      MANAGER         7839 02-APR-81       2975                    207654 MARTIN     SALESMAN        7698 28-SEP-81       1250       1400         307698 BLAKE      MANAGER         7839 01-MAY-81       2850                    307782 CLARK      MANAGER         7839 09-JUN-81       2450                    107788 SCOTT      ANALYST         7566 24-JAN-87       3000                    207839 KING       PRESIDENT            17-NOV-81       5000                    107844 TURNER     SALESMAN        7698 08-SEP-81       1500          0         307876 ADAMS      CLERK           7788 02-APR-87       1100                    207900 JAMES      CLERK           7698 03-DEC-81        950                    307902 FORD       ANALYST         7566 03-DEC-81       3000                    207934 MILLER     CLERK           7782 23-JAN-82       1300                    1014 rows selected.SQL> select deptno,sum(sal) from emp group by deptno;DEPTNO   SUM(SAL)
---------- ----------30       940010       875020      10875SQL> select deptno,sum(sal) from emp having sum(sal)>9000 group by deptno;DEPTNO   SUM(SAL)
---------- ----------30       940020      10875SQL> select deptno,job,sum(sal) from emp group by deptno,job;DEPTNO JOB         SUM(SAL)
---------- --------- ----------20 MANAGER         297520 ANALYST         600010 PRESIDENT       500010 CLERK           130030 SALESMAN        560010 MANAGER         245020 CLERK           190030 MANAGER         285030 CLERK            9509 rows selected.SQL> select deptno,job,sum(sal) from emp group by deptno,job order by 1,2;DEPTNO JOB         SUM(SAL)
---------- --------- ----------10 CLERK           130010 MANAGER         245010 PRESIDENT       500020 ANALYST         600020 CLERK           190020 MANAGER         297530 CLERK            95030 MANAGER         285030 SALESMAN        56009 rows selected.SQL> 

带有ROLLUP和CUBE运算符的GROUP BY

  • 带有ROLLUP或者CUBE的GROUP BY 会通过交叉参考列产生一个超级总计行
  • ROLLUP分组生成一个结果集,包含有通常的分组行和求和值
  • CUBE分组生成一个结果集,包含从ROLLUP里面的行和交叉表行。
SQL> select deptno,job,sum(sal) from emp group by rollup(deptno,job) order by 1,2;DEPTNO JOB         SUM(SAL)
---------- --------- ----------10 CLERK           130010 MANAGER         245010 PRESIDENT       500010                 875020 ANALYST         600020 CLERK           190020 MANAGER         297520                1087530 CLERK            95030 MANAGER         285030 SALESMAN        560030                 94002902513 rows selected.SQL>SQL> select deptno,job,sum(sal) from emp group by deptno,job2  union all3  select deptno,null,sum(sal) from emp group by deptno4  union all5  select null,null,sum(sal) from emp;DEPTNO JOB         SUM(SAL)
---------- --------- ----------20 MANAGER         297520 ANALYST         600010 PRESIDENT       500010 CLERK           130030 SALESMAN        560010 MANAGER         245020 CLERK           190030 MANAGER         285030 CLERK            95030                 940010                 875020                108752902513 rows selected.SQL>  

rollup(a,b,c)

group by a

union all

group by a,b

union all

group by a,b,c

union all

total


cube(a,b,c)

group by a

union all

group by b

union all

group by c

union all

group by a,b

union all

group by a,c

union all

group by b,c

union all

group by a,b,c

union all

total

SQL> 
SQL> select deptno,job,sum(sal) from emp group by deptno,job2  union all3  select deptno,null,sum(sal) from emp group by deptno4  union all5  select null,null,sum(sal) from emp;Execution Plan
----------------------------------------------------------
Plan hash value: 1761893045----------------------------------------------------------------------------
| Id  | Operation           | Name | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      |    15 |   190 |    11  (19)| 00:00:01 |
|   1 |  UNION-ALL          |      |       |       |            |          |
|   2 |   HASH GROUP BY     |      |    11 |   165 |     4  (25)| 00:00:01 |
|   3 |    TABLE ACCESS FULL| EMP  |    14 |   210 |     3   (0)| 00:00:01 |
|   4 |   HASH GROUP BY     |      |     3 |    21 |     4  (25)| 00:00:01 |
|   5 |    TABLE ACCESS FULL| EMP  |    14 |    98 |     3   (0)| 00:00:01 |
|   6 |   SORT AGGREGATE    |      |     1 |     4 |            |          |
|   7 |    TABLE ACCESS FULL| EMP  |    14 |    56 |     3   (0)| 00:00:01 |
----------------------------------------------------------------------------SQL> select deptno,job,sum(sal) from emp group by rollup(deptno,job) order by 1,2;Execution Plan
----------------------------------------------------------
Plan hash value: 52302870-----------------------------------------------------------------------------
| Id  | Operation            | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |      |    11 |   165 |     4  (25)| 00:00:01 |
|   1 |  SORT GROUP BY ROLLUP|      |    11 |   165 |     4  (25)| 00:00:01 |
|   2 |   TABLE ACCESS FULL  | EMP  |    14 |   210 |     3   (0)| 00:00:01 |
-----------------------------------------------------------------------------SQL> 

GROUPING函数

SQL> 
SQL> select deptno,job,sum(sal),grouping(deptno),grouping(job) from emp group by rollup(deptno,job);DEPTNO JOB         SUM(SAL) GROUPING(DEPTNO) GROUPING(JOB)
---------- --------- ---------- ---------------- -------------10 CLERK           1300                0             010 MANAGER         2450                0             010 PRESIDENT       5000                0             010                 8750                0             120 CLERK           1900                0             020 ANALYST         6000                0             020 MANAGER         2975                0             020                10875                0             130 CLERK            950                0             030 MANAGER         2850                0             030 SALESMAN        5600                0             030                 9400                0             129025                1             113 rows selected.SQL> 
SQL> select decode(grouping(deptno)||grouping(job),'01','Subtotal ' || deptno,'11','Total',deptno) deptno,job,sum(sal) from emp group by rollup(deptno,job);DEPTNO                                            JOB         SUM(SAL)
------------------------------------------------- --------- ----------
10                                                CLERK           1300
10                                                MANAGER         2450
10                                                PRESIDENT       5000
Subtotal 10                                                       8750
20                                                CLERK           1900
20                                                ANALYST         6000
20                                                MANAGER         2975
Subtotal 20                                                      10875
30                                                CLERK            950
30                                                MANAGER         2850
30                                                SALESMAN        5600
Subtotal 30                                                       9400
Total                                                            2902513 rows selected.SQL> SQL> select decode(grouping(deptno)||grouping(job),'01','Subtotal ' || deptno,'11','Total',deptno) deptno,job,sum(sal),grouping(deptno),grouping(job) from emp group by rollup(deptno,job);DEPTNO                                            JOB         SUM(SAL) GROUPING(DEPTNO) GROUPING(JOB)
------------------------------------------------- --------- ---------- ---------------- -------------
10                                                CLERK           1300                0             0
10                                                MANAGER         2450                0             0
10                                                PRESIDENT       5000                0             0
Subtotal 10                                                       8750                0             1
20                                                CLERK           1900                0             0
20                                                ANALYST         6000                0             0
20                                                MANAGER         2975                0             0
Subtotal 20                                                      10875                0             1
30                                                CLERK            950                0             0
30                                                MANAGER         2850                0             0
30                                                SALESMAN        5600                0             0
Subtotal 30                                                       9400                0             1
Total                                                            29025                1             113 rows selected.SQL> 

相关内容

热门资讯

东部战区重磅发布 东部战区新闻发言人施毅陆军大校表示,12月29日开始,中国人民解放军东部战区组织陆军、海军、空军、火...
(粤港澳大湾区)澳门青年容甄甄...   中新社广州12月28日电 题:澳门青年容甄甄:大湾区创业“不设限”的逐梦之旅  中新社记者 张璐...
2025“三农”成绩单|筑牢粮...   粮食安全,是“国之大者”。  10月23日,在北大荒集团黑龙江格球山农场有限公司一烘干厂,工人驾...
视频丨赏冰雕品美食 穿唐装游古...   随着元旦临近,不少地方已经提前开启了旅游市场的预热活动。在青海省西宁市城北区的北川青唐城,大型雾...
一线见闻丨一条通道串联三大都市...   “十五五”规划建议提出,要增强区域发展协调性,巩固提升粤港澳大湾区高质量发展动力源作用。广东省中...
爱奇艺回应充25年会员退费难:...   12月28日,话题“男子爱奇艺会员充了25年遇退费难”登上微博热搜。  12月25日,河南许昌,...
30日至2026年1月2日强冷...   央视网消息:据中央气象台网站消息,预计12月30日至2026年1月2日,强冷空气将影响中东部大部...
财政部:2026年继续安排资金...   财政部部长蓝佛安在12月27日至28日举行的全国财政工作会议上表示,明年财政将大力提振消费。深入...
(年终特稿)中国经济这一年:民...   中新社北京12月28日电 (记者 刘亮)2025年,中国民营经济迎风破浪前行,不断在新赛道上跑出...
欧洲最高火山时隔半年再次喷发   位于意大利西西里岛东岸的埃特纳火山于当地时间12月26日开始喷发。  12月27日的画面显示,火...