ORACLE中擴展的group by

擴展的GROUP BY
所謂的擴展的GROUP BY就是使用了分析函數rollup() 和 cube()。

rollup():使分組結果中包含小計及總計信息,並可以傳入多列字段
cube():對做爲參數傳入的每一列都進行小計,多列的時候能顯示優勢。
例:
select id,sum(mount) from tt group by rollup(id);
ID SUM(MOUNT)
---------- ----------
1 60
2 150
3 240
4 210
5 440
1100
select id,sum(mount) from tt group by cube(id);
ID SUM(MOUNT)
---------- ----------
1100
1 60
2 150
3 240
4 210
5 440

或者,用nulls 顯示指定空值的首尾位置:
select id,sum(mount) from tt group by cube(id) order by id nulls last;
註釋:這裏必須要有order by 才能使用nulls last,而且如果group by後面是id的時候nulls last/first 纔有效果,如果是sum(mount)則沒有效果.

SQL> select id,sum(mount) from tt group by rollup(id) order by id desc nulls first ;
ID SUM(MOUNT)
---------- ----------
1100
5 440
4 210
3 240
2 150
1 60
SQL> select id,sum(mount) from tt group by rollup(id) order by id desc nulls last ;
ID SUM(MOUNT)
---------- ----------
5 440
4 210
3 240
2 150
1 60
1100
SQL> select id,sum(mount) from tt group by rollup(id) order by sum(mount) desc nulls last ; //這裏便看不到想要的效果
ID SUM(MOUNT)
---------- ----------
1100
5 440
3 240
4 210
2 150
1 60

下面是一些與rollup、cube聯合使用的函數:
groupping():只能在有rollup或者cube的語句中使用,判斷當前行是否是小計或者 總計行(實質是通過是否列爲空來判斷)。比如,小計行的name列爲空(即小計行),則返回1,不爲空則返回0;
SQL> select id,sum(mount),grouping(id) from tt group by rollup(id) order by id desc nulls first ;
ID SUM(MOUNT) GROUPING(ID)
---------- ---------- ------------
1100 1
5 440 0
4 210 0
3 240 0
2 150 0
1 60 0
SQL> select case grouping(id) when 1 then 'zj' else id end as id,sum(mount) from tt group by cube(id) order by id desc;
ID SUM(MOUNT)
---- ----------
zj 1100
5 440
4 210
3 240
2 150
1 60

grouping_id(col1,col2)計算位向量,如例子中deptno和job在grouping的時候都返回1,則 grouping_id(deptno,job)結果則爲二進制11,即3。job爲空,返回0,而deptno返回1,則10,即2; (可以多列)
例:
SQL> select deptno,job,sum(sal) ,grouping(deptno) a,grouping(job) b,grouping_id(deptno,job) c from emp group by cube(deptno,job) order by deptno;

DEPTNO JOB SUM(SAL) A B C
------ --------- ---------- ---------- ---------- ----------
10 CLERK 1300 0 0 0
10 MANAGER 2450 0 0 0
10 PRESIDENT 5000 0 0 0
10 8750 0 1 1
20 ANALYST 6000 0 0 0
20 CLERK 1900 0 0 0
20 MANAGER 2975 0 0 0
20 10875 0 1 1
30 CLERK 950 0 0 0
30 MANAGER 2850 0 0 0
30 SALESMAN 5600 0 0 0
30 9400 0 1 1
ANALYST 6000 1 0 2
CLERK 4150 1 0 2
MANAGER 8275 1 0 2
PRESIDENT 5000 1 0 2
SALESMAN 5600 1 0 2
29025 1 1 3
它常與having聯繫使用,來篩選結果中的小計或總計的行。其實只需要grouping_id行大於零的都是。
SQL> select deptno,job,sum(sal) ,grouping(deptno) a,grouping(job) b,grouping_id(deptno,job) c from emp group by cube(deptno,job) having grouping_id(deptno,job)>0 order by deptno;
DEPTNO JOB SUM(SAL) A B C
------ --------- ---------- ---------- ---------- ----------
10 8750 0 1 1
20 10875 0 1 1
30 9400 0 1 1
ANALYST 6000 1 0 2
CLERK 4150 1 0 2
MANAGER 8275 1 0 2
PRESIDENT 5000 1 0 2
SALESMAN 5600 1 0 2
29025 1 1 3
註釋:這樣的結果只是比grouping sets子句多了一個最後的總計。

group_id()控制重複值,記錄第一次出現時爲0,第二次出現爲1,第三次出現爲2。
它不接受任何參數。
註釋: group by語句可以同時使用普通列、rollup()和cube()等作爲條件,如果一個列在不同地方出現了多次,結果集可能會重複。同時使用的含義是:普通列加上高級函數的每個結果作爲group by的條件彙總,

SQL> select deptno,job,sum(sal) from emp group by rollup(deptno,job);
DEPTNO JOB SUM(SAL)
------ --------- ----------
10 CLERK 1300
10 MANAGER 2450
10 PRESIDENT 5000
10 8750
20 CLERK 1900
20 ANALYST 6000
20 MANAGER 2975
20 10875
30 CLERK 950
30 MANAGER 2850
30 SALESMAN 5600
30 9400
29025
SQL> select deptno,job,sum(sal) from emp group by deptno,rollup(deptno,job);
DEPTNO JOB SUM(SAL)
------ --------- ----------
10 CLERK 1300
10 MANAGER 2450
10 PRESIDENT 5000
20 CLERK 1900
20 ANALYST 6000
20 MANAGER 2975
30 CLERK 950
30 MANAGER 2850
30 SALESMAN 5600
10 8750
20 10875
30 9400
10 8750
20 10875
30 9400
SQL> select deptno,job,sum(sal) ,group_id() from emp group by deptno,rollup(deptno,job);

DEPTNO JOB SUM(SAL) GROUP_ID()
------ --------- ---------- ----------
10 CLERK 1300 0
10 MANAGER 2450 0
10 PRESIDENT 5000 0
20 CLERK 1900 0
20 ANALYST 6000 0
20 MANAGER 2975 0
30 CLERK 950 0
30 MANAGER 2850 0
30 SALESMAN 5600 0
10 8750 0
20 10875 0
30 9400 0
10 8750 1
20 10875 1
30 9400 1
SQL> select deptno,job,sum(sal) ,group_id() from emp group by deptno,rollup(deptno,job) having group_id()=0;

DEPTNO JOB SUM(SAL) GROUP_ID()
------ --------- ---------- ----------
10 CLERK 1300 0
10 MANAGER 2450 0
10 PRESIDENT 5000 0
20 CLERK 1900 0
20 ANALYST 6000 0
20 MANAGER 2975 0
30 CLERK 950 0
30 MANAGER 2850 0
30 SALESMAN 5600 0
10 8750 0
20 10875 0
30 9400 0


grouping sets子句:
group by後帶grouping sets子句就是隻返回按單個列分組後的統計數據,不返回多個列組合分組的統計數據。
例:Group by grouping sets(A ,B)
產生的分組種數:2種;
第一種:group by A
第二種:group by B

SQL> select deptno,job,sum(sal) from emp group by deptno,job order by deptno;
DEPTNO JOB SUM(SAL)
------ --------- ----------
10 CLERK 1300
10 MANAGER 2450
10 PRESIDENT 5000
20 ANALYST 6000
20 CLERK 1900
20 MANAGER 2975
30 CLERK 950
30 MANAGER 2850
30 SALESMAN 5600
SQL> select deptno,job,sum(sal) from emp group by grouping sets(deptno,job) order by deptno;
DEPTNO JOB SUM(SAL)
------ --------- ----------
10 8750
20 10875
30 9400
ANALYST 6000
PRESIDENT 5000
SALESMAN 5600
CLERK 4150
MANAGER 8275
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章