rollup和grouping函數


轉載: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)
復制代碼

 

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM