經過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)
數據庫