oracle之經過group by產生統計報告

經過group by產生統計報告

Oracle數據庫中的ROLLUP配合group by命令使用,能夠提供信息彙總功能(與"小計"類似)
CUBE,也是GROUP BY子句的一種擴展,能夠返回每個列組合的小計記錄,同時在末尾加上總計記錄。

group by有關知識點:

1)group by rollup
2)group by cube

3)grouping和grouping_id函數

4)grouping set

示例以下:
SQL> select job,deptno,sum(sal) total_sal from emp group by (job,deptno);

JOB               DEPTNO  TOTAL_SAL
--------- ---------- ----------
MANAGER               20           2975
PRESIDENT             10           5000
CLERK                 10           1300
SALESMAN              30           5600
ANALYST               20           6000
MANAGER               30           2850
MANAGER               10           2450
CLERK                 30            950
CLERK                 20           1900

已選擇9行。

18.1 rollup的用法

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

JOB               DEPTNO  TOTAL_SAL
--------- ---------- ----------
CLERK                 10           1300
CLERK                 20           1900
CLERK                 30            950
CLERK                          4150
ANALYST               20           6000
ANALYST                       6000
MANAGER               10           2450
MANAGER               20           2975
MANAGER               30           2850
MANAGER                        8275
SALESMAN              30           5600
SALESMAN                       5600
PRESIDENT             10           5000
PRESIDENT                      5000
                                  29025

15 rows selected.

18.2 cube的用法
SQL> select job,deptno,sum(sal) total_sal from emp group by cube(job,deptno);

JOB               DEPTNO  TOTAL_SAL
--------- ---------- ----------
                                  29025
                      10           8750
                      20          10875
                      30           9400
CLERK                             4150
CLERK                 10           1300
CLERK                 20           1900
CLERK                 30            950
ANALYST                       6000
ANALYST               20           6000
MANAGER                        8275
MANAGER               10           2450
MANAGER               20           2975
MANAGER               30           2850
SALESMAN                       5600
SALESMAN              30           5600
PRESIDENT                      5000
PRESIDENT             10           5000

18 rows selected.

能夠看出,用了rollup的group by子句所產生的所謂的超級聚合就是指在在產生聚合時會從右向左逐個對每一列進行小結,並在結果中生成獨立的一行,同時也會對聚合列生成一個合計列。

這裏的group by後面咱們僅僅接了2列,實際上咱們能夠使用更多列的,這樣的話oracle就會以從右向左的方式來進行逐個小結。

這裏須要注意的是使用了group by和rollup後,其後面的列要用括號括起來,不然將會出現ORA-00933: SQL 命令未正確結束的錯誤。

看看grouping、grouping_id函數是什麼?

18.3 grouping函數和grouping_id函數

GROUPING函數能夠接受一列,返回0或者1。若是列值爲空,那麼GROUPING()返回1;若是列值非空,那麼返回0。GROUPING只能在使用ROLLUP或CUBE的查詢中使用。當須要在返回空值的地方顯示某個值時,GROUPING()就很是有用。

GROUPING函數能夠返回0,1,2,3...能夠分別表示小計,合計等信息。
     
SQL>
SQL> select job,deptno,sum(sal) total_sal,grouping(job) job_grp, grouping(deptno) deptno_grp,grouping_id(job,deptno) total_grp from emp group by cube(job,deptno);

JOB               DEPTNO  TOTAL_SAL    JOB_GRP DEPTNO_GRP  TOTAL_GRP
--------- ---------- ---------- ---------- ---------- ----------
                                  29025              1          1          3
                      10           8750              1          0          2
                      20          10875              1          0          2
                      30           9400              1          0          2
CLERK                          4150                      0          1          1
CLERK                 10           1300              0          0          0
CLERK                 20           1900              0          0          0
CLERK                 30            950              0          0          0
ANALYST                        6000                      0          1          1
ANALYST               20           6000              0          0          0
MANAGER                        8275                      0          1          1
MANAGER               10           2450              0          0          0
MANAGER               20           2975              0          0          0
MANAGER               30           2850              0          0          0
SALESMAN                       5600                      0          1          1
SALESMAN              30           5600              0          0          0
PRESIDENT                      5000                      0          1          1
PRESIDENT             10           5000             0          0          0

已選擇18行。


可是咱們大多數狀況下須要在查詢的結果集的彙總列加上「合計」,怎麼辦呢?用grouping和grouping_id函數,而後再用decode函數判斷一下是否爲空就能夠了

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

 GROUP_COL  TOTAL_SAL
---------- ----------
         0       1300
         0       1900
         0        950
         1       4150
         0       6000
         1       6000
         0       2450
         0       2975
         0       2850
         1       8275
         0       5600
         1       5600
         0       5000
         1       5000
         3      29025

已選擇15行。

SQL>select decode(grouping_id(job,deptno),1,'合計',3,'總計',job||deptno) as group_col,sum(sal) total_sal
from emp group by rollup(job,deptno);

GROUP_COL                                          TOTAL_SAL
------------------------------------------------- ----------
CLERK10                                                     1300
CLERK20                                                     1900
CLERK30                                                  950
合計                                                            4150
ANALYST20                                                6000
合計                                                         6000
MANAGER10                                              2450
MANAGER20                                              2975
MANAGER30                                              2850
合計                                                             8275
SALESMAN30                                             5600
合計                                                            5600
PRESIDENT10                                             5000
合計                                                         5000
總計                                                            29025

18.4 grouping sets

grouping sets用於在一個select語句中定義多個grouping, 至關於將grouping set中的多個grouping組合後再UNION ALL。

例1
SELECT null,job,mgr, AVG(sal)
FROM emp
GROUP BY(job,mgr)
union all
SELECT deptno, job, null,AVG(sal)
FROM emp
GROUP by (deptno,job);

例2=例1, 但使用了grouping sets
            
SELECT deptno,job,mgr, AVG(sal)
FROM emp
GROUP BY grouping sets ((deptno,job),(job,mgr));

    DEPTNO JOB                  MGR   AVG(SAL)
---------- --------- ---------- ----------
               CLERK               7902        800
               PRESIDENT                      5000
               CLERK               7698        950
               CLERK               7788       1100
               CLERK               7782       1300
               SALESMAN            7698       1400
               MANAGER             7839     2758.33333
               ANALYST             7566       3000
        20     CLERK                           950
        30     SALESMAN                       1400
        20     MANAGER                        2975
        30     CLERK                           950
        10     PRESIDENT                      5000
        30     MANAGER                        2850
        10     CLERK                          1300
        10     MANAGER                       2450
        20     ANALYST                        3000

已選擇17行。

Oracle給出了一個小表,能夠代表grouping sets和 union all的關係:

GROUPING SETS Statements             Equivalent GROUP BY Statements
-------------------------------------------------------------------------------
GROUP BY GROUPING SETS(a, b, c)            GROUP BY a UNION ALL
                        GROUP BY b UNION ALL
                        GROUP BY c

GROUP BY GROUPING SETS(a, b,(b, c))            GROUP BY a UNION ALL
                        GROUP BY b UNION ALL
                        GROUP BY b, c
        
GROUP BY GROUPING SETS((a, b, c))            GROUP BY a, b, c

GROUP BY GROUPING SETS(a, (b), ())            GROUP BY a UNION ALL
                        GROUP BY b UNION ALL
                        GROUP BY ()

GROUP BY GROUPING SETS(a,ROLLUP(b, c))        GROUP BY a UNION ALL
                        GROUP BY ROLLUP(b, c)

數據庫

相關文章
相關標籤/搜索