轉載:http://blog.itpub.net/519536/viewspace-610995/
本文通過演示給出Oracle ROLLUP分組函數的用法,體驗一下Oracle在統計查詢領域中的函數魅力。ROLLUP分組函數可以理解為Group By分組函數封裝后的精簡用法,這里同時給出ROLLUP的Group By的改寫思路。
1.初始化實驗壞境
1)創建測試表group_test
SECOOLER@ora11g> create table group_test (group_id int, job varchar2(10), name varchar2(10), salary int);
Table created.
2)初始化數據
insert into group_test values (10,'Coding', 'Bruce',1000);
insert into group_test values (10,'Programmer','Clair',1000);
insert into group_test values (10,'Architect', 'Gideon',1000);
insert into group_test values (10,'Director', 'Hill',1000);
insert into group_test values (20,'Coding', 'Jason',2000);
insert into group_test values (20,'Programmer','Joey',2000);
insert into group_test values (20,'Architect', 'Martin',2000);
insert into group_test values (20,'Director', 'Michael',2000);
insert into group_test values (30,'Coding', 'Rebecca',3000);
insert into group_test values (30,'Programmer','Rex',3000);
insert into group_test values (30,'Architect', 'Richard',3000);
insert into group_test values (30,'Director', 'Sabrina',3000);
insert into group_test values (40,'Coding', 'Samuel',4000);
insert into group_test values (40,'Programmer','Susy',4000);
insert into group_test values (40,'Architect', 'Tina',4000);
insert into group_test values (40,'Director', 'Wendy',4000);
commit;
3)初始化之后的數據情況如下:
SECOOLER@ora11g> set pages 100
SECOOLER@ora11g> select * from group_test;
GROUP_ID JOB NAME SALARY
---------- ---------- ---------- ----------
10 Coding Bruce 1000
10 Programmer Clair 1000
10 Architect Gideon 1000
10 Director Hill 1000
20 Coding Jason 2000
20 Programmer Joey 2000
20 Architect Martin 2000
20 Director Michael 2000
30 Coding Rebecca 3000
30 Programmer Rex 3000
30 Architect Richard 3000
30 Director Sabrina 3000
40 Coding Samuel 4000
40 Programmer Susy 4000
40 Architect Tina 4000
40 Director Wendy 4000
16 rows selected.
2.先看一下普通分組的效果:對group_id進行普通的group by操作---按照小組進行分組
SECOOLER@ora11g> select group_id,sum(salary) from group_test group by group_id;
GROUP_ID SUM(SALARY)
---------- -----------
30 12000
20 8000
40 16000
10 4000
3.對group_id進行普通的roolup操作---按照小組進行分組,同時求總計
SECOOLER@ora11g> select group_id,sum(salary) from group_test group by rollup(group_id);
GROUP_ID SUM(SALARY)
---------- -----------
10 4000
20 8000
30 12000
40 16000
40000
使用Group By語句翻譯一下上面的SQL語句如下(union all一個統計所有數據的行):
SECOOLER@ora11g> select group_id,sum(salary) from group_test group by group_id
2 union all
3 select null, sum(salary) from group_test
4 order by 1;
GROUP_ID SUM(SALARY)
---------- -----------
10 4000
20 8000
30 12000
40 16000
40000
4.再看一個rollup兩列的情況
SECOOLER@ora11g> select group_id,job,sum(salary) from group_test group by rollup(group_id, job);
GROUP_ID JOB SUM(SALARY)
---------- ---------- -----------
10 Coding 1000
10 Director 1000
10 Architect 1000
10 Programmer 1000
10 4000
20 Coding 2000
20 Director 2000
20 Architect 2000
20 Programmer 2000
20 8000
30 Coding 3000
30 Director 3000
30 Architect 3000
30 Programmer 3000
30 12000
40 Coding 4000
40 Director 4000
40 Architect 4000
40 Programmer 4000
40 16000
40000
21 rows selected.
上面的SQL語句該如何使用Group By進行翻譯呢?
答案如下:
SECOOLER@ora11g> select group_id,job,sum(salary) from group_test group by group_id, job
2 union all
3 select group_id,null,sum(salary) from group_test group by group_id
4 union all
5 select null,null,sum(salary) from group_test
6 order by 1,2;
GROUP_ID JOB SUM(SALARY)
---------- ---------- -----------
10 Architect 1000
10 Coding 1000
10 Director 1000
10 Programmer 1000
10 4000
20 Architect 2000
20 Coding 2000
20 Director 2000
20 Programmer 2000
20 8000
30 Architect 3000
30 Coding 3000
30 Director 3000
30 Programmer 3000
30 12000
40 Architect 4000
40 Coding 4000
40 Director 4000
40 Programmer 4000
40 16000
40000
21 rows selected.
5.補充一步,體驗一下GROUPING函數的效果
直接看效果就OK啦:
SECOOLER@ora11g> select group_id,job,grouping(GROUP_ID),grouping(JOB),sum(salary) from group_test group by rollup(group_id, job);
GROUP_ID JOB GROUPING(GROUP_ID) GROUPING(JOB) SUM(SALARY)
---------- ---------- ------------------ ------------- -----------
10 Coding 0 0 1000
10 Director 0 0 1000
10 Architect 0 0 1000
10 Programmer 0 0 1000
10 0 1 4000
20 Coding 0 0 2000
20 Director 0 0 2000
20 Architect 0 0 2000
20 Programmer 0 0 2000
20 0 1 8000
30 Coding 0 0 3000
30 Director 0 0 3000
30 Architect 0 0 3000
30 Programmer 0 0 3000
30 0 1 12000
40 Coding 0 0 4000
40 Director 0 0 4000
40 Architect 0 0 4000
40 Programmer 0 0 4000
40 0 1 16000
1 1 40000
21 rows selected.
看出來什么效果了么?
有的同學還是沒有看出來,小小的解釋一下:
如果顯示“1”表示GROUPING函數對應的列(例如JOB字段)是由於ROLLUP函數所產生的空值對應的信息,即對此列進行匯總計算后的結果。
如果顯示“0”表示此行對應的這列參未與ROLLUP函數分組匯總活動。
如果還是沒有理解清楚,請參見Oracle官方文檔中的描述內容:“Using a single column as its argument, GROUPING returns 1 when it encounters a NULL value created by a ROLLUP or CUBE operation. That is, if the NULL indicates the row is a subtotal, GROUPING returns a 1. Any other type of value, including a stored NULL, returns a 0.”
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
轉載:http://www.cnblogs.com/lxh1076/p/5697929.html
group by 后使用 rollup 子句總結
group by 后使用 rollup 子句總結
一、如何理解group by 后帶 rollup 子句所產生的效果
group by 后帶 rollup 子句的功能可以理解為:先按一定的規則產生多種分組,然后按各種分組統計數據(至於統計出的數據是求和還是最大值還是平均值等這就取決於SELECT后的聚合函數)。因此要搞懂group by 后帶 rollup 子句的用法主要是搞懂它是如何按一定的規則產生多種分組的。另group by 后帶 rollup 子句所返回的結果集,可以理解為各個分組所產生的結果集的並集且沒有去掉重復數據。下面舉例說明:
1、 對比沒有帶rollup 的goup by
例:Group by A ,B
產生的分組種數:1種;
即group by A,B
返回結果集:也就是這一種分組的結果集。
2、 帶rollup 但 group by 與 rollup 之間沒有任何內容
例1:Group by rollup(A ,B)
產生的分組種數:3 種;
第一種:group by A,B
第二種:group by A
第三種:group by NULL
(說明:本沒有group by NULL 的寫法,在這里指是為了方便說明,而采用之。含義是:沒有分組,也就是所有數據做一個統計。例如聚合函數是SUM的話,那就是對所有滿足條件的數據進行求和。此寫法的含義下同)
返回結果集:為以上三種分組統計結果集的並集且未去掉重復數據。
例2:Group by rollup(A ,B,C)
產生的分組種數:4 種;
第一種:group by A,B,C
第二種:group by A,B
第三種:group by A
第四種:group by NULL
返回結果集:為以上四種分組統計結果集的並集且未去掉重復數據。
3、 帶rollup 但 group by 與 rollup 之間還包含有列信息
例1:Group by A , rollup(A ,B)
產生的分組種數:3 種;
第一種:group by A,A,B 等價於 group by A,B
第二種:group by A,A 等價於 group by A
第三種:group by A,NULL 等價於 group by A
返回結果集:為以上三種分組統計結果集的並集且未去掉重復數據。
例2:Group by C , rollup(A ,B)
產生的分組種數:3 種;
第一種:group by C,A,B
第二種:group by C,A
第三種:group by C,NULL 等價於 group by C
返回結果集:為以上三種分組統計結果集的並集且未去掉重復數據。
4、 帶rollup 且rollup子句括號內又使用括號對列進行組合
例1:Group by rollup((A ,B))
產生的分組種數:2 種;
第一種:group by A,B
第二種:group by NULL
返回結果集:為以上兩種分組統計結果集的並集且未去掉重復數據。
例2:Group by rollup(A ,(B,C))
產生的分組種數:3 種;
第一種:group by A,B,C
第二種:group by A
第三種:group by NULL
返回結果集:為以上三種分組統計結果集的並集且未去掉重復數據。
注:對這種情況,可以理解為幾個列被括號括在一起時,就只能被看成一個整體,分組時不需要再細化。因此也可推斷rollup括號內也頂多加到一重括號,加多重了應該沒有任何意義(這個推斷我沒有做驗證的哦)。
二、與rollup組合使用的其它幾個輔助函數
1、grouping()函數
必須接受一列且只能接受一列做為其參數。參數列值為空返回1,參數列值非空返回0。
2、grouping_id()函數
必須接受一列或多列做為其參數。
返回值為按參數排列順序,依次對各個參數使用grouping()函數,並將結果值依次串成一串二進制數然后再轉化為十進制所得到的值。
例如:grouping(A) = 0 ; grouping(B) = 1;
則:grouping_id(A,B) = (01)2 = 1;
grouping_id(B,A) = (10)2 =2;
3、group_id()函數
調用時不需要且不能傳入任何參數。
返回值為某個特定的分組出現的重復次數(第一大點中的第3種情況中往往會產生重復的分組)。重復次數從0開始,例如某個分組第一次出現則返回值為0,第二次出現時返回值為1,……,第n次出現返回值為n-1。
注:使用以上三個函數往往是為了過濾掉一部分統計數據,而達到美化統計結果的作用。
三、group by 后帶rollup子句與 group by 后帶cube子句區別
group by 后帶rollup子句與 group by 后帶cube子句的唯一區別就是:
帶cube子句的group by 會產生更多的分組統計數據。cube后的列有多少種組合(注意組合是與順序無關的)就會有多少種分組。
例:Group by cube(A ,B,C)
產生的分組種數:8 種;
第一種:group by A,B,C
第二種:group by A,B
第三種:group by A,C
第四種:group by B,C
第五種:group by C
第六種:group by B
第七種:group by A
第八種:group by NULL
返回結果集:為以上八種分組統計結果集的並集且未去掉重復數據。
四、group by 后帶grouping sets子句
group by 后帶grouping sets子句效果就是只返回小記記錄,即只返回按單個列分組后的統計數據,不返回多個列組合分組的統計數據。
例1:Group by grouping sets(A )
產生的分組種數:1 種;
第一種:group by A
返回結果集:即為以上一種分組的統計結果集。
例2:Group by grouping sets(A ,B)
產生的分組種數:2 種;
第一種:group by A
第二種:group by B
返回結果集:為以上兩種分組統計結果集的並集且未去掉重復數據。
例3:Group by grouping sets (A ,B,C)
產生的分組種數:3 種;
第一種:group by A
第二種:group by B
第三種:group by C
返回結果集:為以上三種分組統計結果集的並集且未去掉重復數據。
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
轉載:http://www.cnblogs.com/fangyz/p/5813916.html
2.grouping( )
grouping函數用來區分NULL值,這里NULL值有2種情況,一是原本表中的數據就為NULL,二是由rollup、cube、grouping sets生成的NULL值。
當為第一種情況中的空值時,grouping(NULL)返回0;當為第二種情況中的空值時,grouping(NULL)返回1。實例如下,從結果中可以看到第二個結果集中原本為null的數據由於grouping函數為1,故顯示ROLLUP-NULL字符串。
select teacherAddress,ascriptionInstitute,COUNT(teacherId ) from teacher group by teacherAddress,ascriptionInstitute select teacherAddress,ascriptionInstitute,COUNT(teacherId ) from teacher group by rollup(teacherAddress,ascriptionInstitute) select ISNULL(teacherAddress,case when GROUPING(teacherAddress)=1 then 'ROLLUP-NULL' end) as teacherAddress, ISNULL(ascriptionInstitute,case when GROUPING(ascriptionInstitute)=1 then 'ROLLUP-NULL' end) as ascriptionInstitute, COUNT(teacherId ) from teacher group by rollup(teacherAddress,ascriptionInstitute)