rolllup巧用

Posted ClarkYu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了rolllup巧用相关的知识,希望对你有一定的参考价值。

--构造环境
drop table dept purge;
drop table emp purge;
create table dept as select * from scott.dept;
create table emp  as select * from scott.emp;


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


set term off
set heading on
set verify off
set feedback off
set linesize 2000
set pagesize 30000
set long 999999999
set longchunksize 999999
set autotrace off




---写法1
SELECT  a.dname,b.job,SUM(b.sal) sum_sal
FROM dept a,emp b
WHERE a.deptno = b.deptno
GROUP  BY a.dname,b.job;


DNAME          JOB          SUM_SAL
-------------- --------- ----------
SALES          MANAGER         2850
SALES          CLERK            950
ACCOUNTING     MANAGER         2450
ACCOUNTING     PRESIDENT       5000
ACCOUNTING     CLERK           1300
SALES          SALESMAN        5600
RESEARCH       MANAGER         2975
RESEARCH       ANALYST         6000
RESEARCH       CLERK           1900




/*


不错不错,自我陶醉中....
   停!先别得意,有人跑来说希望能增加一列总的汇总。
      等等,更变态的需求来了,希望能得到不同DNAME的各自汇总!


*/






---写法2(没办法,先想到如下一个办法来实现楼上的变态需求)


set autotrace on 
select * from (
SELECT  a.dname,b.job,SUM(b.sal) sum_sal
FROM dept a,emp b
WHERE a.deptno = b.deptno
GROUP  BY a.dname,b.job
UNION ALL
--实现了部门的小计
SELECT  a.dname,NULL, SUM(b.sal) sum_sal
FROM dept a,emp b
WHERE a.deptno = b.deptno
GROUP  BY a.dname
UNION ALL
--实现了所有部门总的合计
SELECT  NULL,NULL, SUM(b.sal) sum_sal
FROM dept a,emp b
WHERE a.deptno = b.deptno)
order by dname;


DNAME          JOB          SUM_SAL
-------------- --------- ----------
ACCOUNTING     CLERK           1300
ACCOUNTING     MANAGER         2450
ACCOUNTING     PRESIDENT       5000
ACCOUNTING                     8750
RESEARCH       CLERK           1900
RESEARCH       MANAGER         2975
RESEARCH       ANALYST         6000
RESEARCH                      10875
SALES          CLERK            950
SALES          MANAGER         2850
SALES          SALESMAN        5600
SALES                          9400
                              29025


union all 合并笨办法产生的执行计划
-------------------------------------------------------------------------------
Plan hash value: 2979078843
-------------------------------------------------------------------------------
| Id  | Operation              | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------
|   0 | SELECT STATEMENT       |      |    29 |   812 |    23  (22)| 00:00:01 |
|   1 |  SORT ORDER BY         |      |    29 |   812 |    23  (22)| 00:00:01 |
|   2 |   VIEW                 |      |    29 |   812 |    22  (19)| 00:00:01 |
|   3 |    UNION-ALL           |      |       |       |            |          |
|   4 |     HASH GROUP BY      |      |    14 |   756 |     8  (25)| 00:00:01 |
|*  5 |      HASH JOIN         |      |    14 |   756 |     7  (15)| 00:00:01 |
|   6 |       TABLE ACCESS FULL| DEPT |     4 |    88 |     3   (0)| 00:00:01 |
|   7 |       TABLE ACCESS FULL| EMP  |    14 |   448 |     3   (0)| 00:00:01 |
|   8 |     HASH GROUP BY      |      |    14 |   672 |     8  (25)| 00:00:01 |
|*  9 |      HASH JOIN         |      |    14 |   672 |     7  (15)| 00:00:01 |
|  10 |       TABLE ACCESS FULL| DEPT |     4 |    88 |     3   (0)| 00:00:01 |
|  11 |       TABLE ACCESS FULL| EMP  |    14 |   364 |     3   (0)| 00:00:01 |
|  12 |     SORT AGGREGATE     |      |     1 |    39 |            |          |
|* 13 |      HASH JOIN         |      |    14 |   546 |     7  (15)| 00:00:01 |
|  14 |       TABLE ACCESS FULL| DEPT |     4 |    52 |     3   (0)| 00:00:01 |
|  15 |       TABLE ACCESS FULL| EMP  |    14 |   364 |     3   (0)| 00:00:01 |
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   5 - access("A"."DEPTNO"="B"."DEPTNO")
   9 - access("A"."DEPTNO"="B"."DEPTNO")
  13 - access("A"."DEPTNO"="B"."DEPTNO")
统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
         18  consistent gets
          0  physical reads
          0  redo size
        783  bytes sent via SQL*Net to client
        416  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
         13  rows processed
         












---写法3(学本领很重要,如果你会rollup神功,性能就能大幅度提升,SQL书写也不麻烦了)


set autotrace on 
SELECT  a.dname,b.job, SUM(b.sal) sum_sal
FROM dept a,emp b 
WHERE a.deptno = b.deptno
GROUP  BY ROLLUP(a.dname,b.job);


DNAME          JOB          SUM_SAL
-------------- --------- ----------
SALES          CLERK            950
SALES          MANAGER         2850
SALES          SALESMAN        5600
SALES                          9400
RESEARCH       CLERK           1900
RESEARCH       ANALYST         6000
RESEARCH       MANAGER         2975
RESEARCH                      10875
ACCOUNTING     CLERK           1300
ACCOUNTING     MANAGER         2450
ACCOUNTING     PRESIDENT       5000
ACCOUNTING                     8750
                              29025


rollup写法产生的执行计划
-----------------------------------------------------------------------------
Plan hash value: 1037965942
-----------------------------------------------------------------------------
| Id  | Operation            | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |      |    14 |   756 |     8  (25)| 00:00:01 |
|   1 |  SORT GROUP BY ROLLUP|      |    14 |   756 |     8  (25)| 00:00:01 |
|*  2 |   HASH JOIN          |      |    14 |   756 |     7  (15)| 00:00:01 |
|   3 |    TABLE ACCESS FULL | DEPT |     4 |    88 |     3   (0)| 00:00:01 |
|   4 |    TABLE ACCESS FULL | EMP  |    14 |   448 |     3   (0)| 00:00:01 |
-----------------------------------------------------------------------------


Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("A"."DEPTNO"="B"."DEPTNO")
统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          6  consistent gets
          0  physical reads
          0  redo size
        778  bytes sent via SQL*Net to client
        416  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
         13  rows processed


--在这里应该可以清楚的发现,表的访问次数比union all硬平畴的要少,而且COST和逻辑读也少的多!


---写法4(如果你想再多一个维度,比如再增加雇佣年份的统计,之前union all硬拼凑的方法要崩溃了吧,不过rollup轻松搞定,如下)


SELECT to_char(b.hiredate,‘yyyy‘) hire_year,a.dname,b.job, SUM(sal) sum_sal
FROM dept a,emp b 
WHERE a.deptno = b.deptno
GROUP BY ROLLUP(to_char(b.hiredate,‘yyyy‘),a.dname,b.job);


HIRE DNAME          JOB          SUM_SAL
---- -------------- --------- ----------
1980 RESEARCH       CLERK            800
1980 RESEARCH                        800
1980                                 800
1981 SALES          CLERK            950
1981 SALES          MANAGER         2850
1981 SALES          SALESMAN        5600
1981 SALES                          9400
1981 RESEARCH       ANALYST         3000
1981 RESEARCH       MANAGER         2975
1981 RESEARCH                       5975
1981 ACCOUNTING     MANAGER         2450
1981 ACCOUNTING     PRESIDENT       5000
1981 ACCOUNTING                     7450
1981                               22825
1982 ACCOUNTING     CLERK           1300
1982 ACCOUNTING                     1300
1982                                1300
1987 RESEARCH       CLERK           1100
1987 RESEARCH       ANALYST         3000
1987 RESEARCH                       4100
1987                                4100
                                   29025      
                                   
执行计划
----------------------------------------------------------------------------
Plan hash value: 1037965942
-----------------------------------------------------------------------------
| Id  | Operation            | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |      |    14 |   882 |     8  (25)| 00:00:01 |
|   1 |  SORT GROUP BY ROLLUP|      |    14 |   882 |     8  (25)| 00:00:01 |
|*  2 |   HASH JOIN          |      |    14 |   882 |     7  (15)| 00:00:01 |
|   3 |    TABLE ACCESS FULL | DEPT |     4 |    88 |     3   (0)| 00:00:01 |
|   4 |    TABLE ACCESS FULL | EMP  |    14 |   574 |     3   (0)| 00:00:01 |
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("A"."DEPTNO"="B"."DEPTNO")
统计信息
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          6  consistent gets
          0  physical reads
          0  redo size
       1107  bytes sent via SQL*Net to client
        427  bytes received via SQL*Net from client
          3  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
         22  rows processed
         


--看官们注意到了吗,多了一个维度的统计,无论是COST还是逻辑读,都没有增加,够帅!     






---写法5 (另外,不止是增加维度,更换维度的次序,对rollup 也是轻而易举的事,如下)


SELECT  b.job,a.dname, SUM(b.sal) sum_sal
FROM dept a,emp b 
WHERE a.deptno = b.deptno
GROUP  BY ROLLUP(b.job,a.dname);


JOB       DNAME             SUM_SAL
--------- -------------- ----------
CLERK     SALES                 950
CLERK     RESEARCH             1900
CLERK     ACCOUNTING           1300
CLERK                          4150
ANALYST   RESEARCH             6000
ANALYST                        6000
MANAGER   SALES                2850
MANAGER   RESEARCH             2975
MANAGER   ACCOUNTING           2450
MANAGER                        8275
SALESMAN  SALES                5600
SALESMAN                       5600
PRESIDENT ACCOUNTING           5000
PRESIDENT                      5000
                              29025   
                              
                              
                              
--------------------- 部分ROLLUP分组---------------------------------------
SELECT to_char(b.hiredate,‘yyyy‘) hire_year,a.dname,b.job, SUM(sal) sum_sal
FROM dept a,emp b 
WHERE a.deptno = b.deptno
GROUP BY to_char(b.hiredate,‘yyyy‘),a.dname,ROLLUP(b.job); 

以上是关于rolllup巧用的主要内容,如果未能解决你的问题,请参考以下文章

巧用cssText属性

audacity怎么用

MVC部分视图的巧用

巧用Zotero搜索引擎,查找相关文献!

巧用渐变实现高级感拉满的背景光动画

异或巧用:Single Number