程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle教程 >> GROUP BY的擴展,GROUPBY擴展

GROUP BY的擴展,GROUPBY擴展

編輯:Oracle教程

GROUP BY的擴展,GROUPBY擴展


GROUP BY的擴展主要包括ROLLUP,CUBE,GROUPING SETS三種形式。

ROLLUP

rollup相對於簡單的分組合計增加了小計和合計,解釋起來會比較抽象,下面我們來看看具體事例。

例1,統計不同部門工資的總和和所有部門工資的總和。

SQL> select deptno,sum(sal) from emp group by rollup(deptno);

    DEPTNO   SUM(SAL)
---------- ----------
        10       8750
        20      10875
        30       9400
                29025

例2,該例中先對deptno進行分組,再對job進行分組

SQL> select deptno,job,sum(sal) from emp group by rollup(deptno,job);

    DEPTNO JOB           SUM(SAL)
---------- --------- ----------
        10 CLERK           1300    --10號部門中JOB為CLERK的工資的總和
        10 MANAGER         2450
        10 PRESIDENT       5000
        10                 8750    --10號所有工種工資的總和
        20 CLERK           1900
        20 ANALYST         6000
        20 MANAGER         2975
        20                10875
        30 CLERK            950
        30 MANAGER         2850
        30 SALESMAN        5600
        30                 9400
                          29025   --所有部門,所有工種工資的總和
13 rows selected.

如果要用普通的分組函數實現,可用UNION ALL語句:

--實現單個部門,單個工種的工資的總和
select deptno,job,sum(sal) from emp group by deptno,job union all
--實現單個部門工資的總和
select deptno,null,sum(sal) from emp group by deptno union all
--實現所有部門工資的總和
select null,null,sum(sal) from emp order by 1,2

下面我們分別來看看兩者的執行計劃及統計信息,

ROLLUP語句:

Execution Plan
-----------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |        |     11 |    132 |      3  (34)| 00:00:01 |
|   1 |  SORT GROUP BY ROLLUP|        |     11 |    132 |      3  (34)| 00:00:01 |
|   2 |   TABLE ACCESS FULL  |   EMP  |     14 |    168 |      2   (0)| 00:00:01 |
-----------------------------------------------------------------------------
Statistics
----------------------------------------------------------
      0  recursive calls
      0  db block gets
      2  consistent gets
      0  physical reads
      0  redo size
    895  bytes sent via SQL*Net to client
    519  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語句:

Execution Plan
-----------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |        |     15 |    150 |      9  (34)| 00:00:01 |
|   1 |  SORT ORDER BY       |        |     15 |    150 |      8  (75)| 00:00:01 |
|   2 |   UNION-ALL          |        |        |        |             |          |
|   3 |    HASH GROUP BY     |        |     11 |    132 |      3  (34)| 00:00:01 |
|   4 |     TABLE ACCESS FULL|   EMP  |     14 |    168 |      2   (0)| 00:00:01 |
|   5 |    HASH GROUP BY     |        |      3 |     15 |      3  (34)| 00:00:01 |
|   6 |     TABLE ACCESS FULL|   EMP  |     14 |     70 |      2   (0)| 00:00:01 |
|   7 |    SORT AGGREGATE    |        |      1 |      3 |             |          |
|   8 |     TABLE ACCESS FULL|   EMP  |     14 |     42 |      2   (0)| 00:00:01 |
-----------------------------------------------------------------------------

Statistics ---------------------------------------------------------- 0 recursive calls 0 db block gets 6 consistent gets 0 physical reads 0 redo size 895 bytes sent via SQL*Net to client 519 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 1 sorts (memory) 0 sorts (disk) 13 rows processed

不難看出,相同的功能實現,ROLLUP相對於UNION ALL效率有了極大的提升。

 

CUBE

cube相對於rollup,結果輸出更加詳細。

例1,在本例中還不是很明顯。

SQL> select deptno,sum(sal) from emp group by cube(deptno);

    DEPTNO   SUM(SAL)
---------- ----------
                29025
        10       8750
        20      10875
        30       9400

例2,相對於rollup,cube還對工種這一列進行了專門的匯總。

SQL> select deptno,job,sum(sal) from emp group by cube(deptno,job);

    DEPTNO JOB           SUM(SAL)
---------- --------- ----------
                          29025
           CLERK           4150
           ANALYST         6000
           MANAGER         8275
           SALESMAN        5600
           PRESIDENT       5000
       10                  8750
       10  CLERK           1300
       10  MANAGER         2450
       10  PRESIDENT       5000
       20                 10875
       20  CLERK           1900
       20  ANALYST         6000
       20  MANAGER         2975
       30                  9400
       30  CLERK            950
       30  MANAGER         2850
       30  SALESMAN        5600
18 rows selected.

 

GROUPING SETS

GROUPING SETS相對於ROLLUP和CUBE,結果是分類統計的,可讀性更好一些。

例1:

SQL> select deptno,job,to_char(hiredate,'yyyy')hireyear,sum(sal) from emp group by grouping sets(deptno,job,to_char(hiredate,'yyyy'));

    DEPTNO JOB         HIRE   SUM(SAL)
---------- ---------   ---- ----------
           CLERK                  4150
           SALESMAN               5600
           PRESIDENT              5000
           MANAGER                8275
           ANALYST                6000
       30                         9400
       20                        10875
       10                         8750
                        1987      4100
                        1980       800
                        1982      1300
                        1981     22825

例2:

SQL> select deptno,job,sum(sal) from emp group by grouping sets(deptno,job);

    DEPTNO JOB           SUM(SAL)
---------- ---------   ----------
           CLERK             4150
           SALESMAN          5600
           PRESIDENT         5000
           MANAGER           8275
           ANALYST           6000
        30                   9400
        20                  10875
        10                   8750
8 rows selected.

對於該例,如何用UNION ALL實現呢?

select null deptno,job,sum(sal) from emp group by job
union all
select deptno,null,sum(sal) from emp group by deptno;

兩者的執行計劃及統計信息分別如下:

GROUPING SETS:

Execution Plan
--------------------------------------------------------------------------------------------------------
| Id  | Operation                   | Name                      | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                           |    11 |   352 |    10  (20)| 00:00:01 |
|   1 |  TEMP TABLE TRANSFORMATION  |                           |       |       |            |          |
|   2 |   LOAD AS SELECT            | SYS_TEMP_0FD9D6795_E71F79 |       |       |            |          |
|   3 |    TABLE ACCESS FULL        | EMP                       |    14 |   168 |     2   (0)| 00:00:01 |
|   4 |   LOAD AS SELECT            | SYS_TEMP_0FD9D6796_E71F79 |       |       |            |          |
|   5 |    HASH GROUP BY            |                           |     1 |    19 |     3  (34)| 00:00:01 |
|   6 |     TABLE ACCESS FULL       | SYS_TEMP_0FD9D6795_E71F79 |     1 |    19 |     2   (0)| 00:00:01 |
|   7 |   LOAD AS SELECT            | SYS_TEMP_0FD9D6796_E71F79 |       |       |            |          |
|   8 |    HASH GROUP BY            |                           |     1 |    26 |     3  (34)| 00:00:01 |
|   9 |     TABLE ACCESS FULL       | SYS_TEMP_0FD9D6795_E71F79 |     1 |    26 |     2   (0)| 00:00:01 |
|  10 |   VIEW                      |                           |     1 |    32 |     2   (0)| 00:00:01 |
|  11 |    TABLE ACCESS FULL        | SYS_TEMP_0FD9D6796_E71F79 |     1 |    32 |     2   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------------
Statistics
----------------------------------------------------------
      4  recursive calls
     24  db block gets
     17  consistent gets
      3  physical reads
   1596  redo size
    819  bytes sent via SQL*Net to client
    519  bytes received via SQL*Net from client
      2  SQL*Net roundtrips to/from client
      0  sorts (memory)
      0  sorts (disk)
      8  rows processed

UNION ALL:

----------------------------------------------------------------------------
| Id  | Operation           | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |       |     8 |    65 |     6  (67)| 00:00:01 |
|   1 |  UNION-ALL          |       |       |       |            |          |
|   2 |   HASH GROUP BY     |       |     5 |    50 |     3  (34)| 00:00:01 |
|   3 |    TABLE ACCESS FULL|  EMP  |    14 |   140 |     2   (0)| 00:00:01 |
|   4 |   HASH GROUP BY     |       |     3 |    15 |     3  (34)| 00:00:01 |
|   5 |    TABLE ACCESS FULL|  EMP  |    14 |    70 |     2   (0)| 00:00:01 |
----------------------------------------------------------------------------

Statistics
----------------------------------------------------------
      0  recursive calls
      0  db block gets
      4  consistent gets
      0  physical reads
      0  redo size
    819  bytes sent via SQL*Net to client
    519  bytes received via SQL*Net from client
      2  SQL*Net roundtrips to/from client
      0  sorts (memory)
      0  sorts (disk)
      8  rows processed

和rollup不同的是,grouping sets的效率竟然比同等功能的union all語句低,這實現有點出乎意料。看來,也不可盲目應用Oracle提供的方案,至少,在本例中是如此。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved