group by后使用rollup子句總結(jié)

今天接觸到了group by后帶rollup子句的用法(真是丑死人了,接觸ORACLE一兩年了今天才知道還有這樣一個用法),group by后帶rollup子句這個子句所產(chǎn)生的功能實在是太高級了,見了就高興。但學(xué)習(xí)完后感覺也沒什么的,很簡單的。

下面按我的理解簡單總結(jié)一下:

一、如何理解group by帶rollup子句所產(chǎn)生的效果

group by后帶rollup子句的功能可以理解為:先按一定的規(guī)則產(chǎn)生多種分組,然后按各種分組統(tǒng)計數(shù)據(jù)(至于統(tǒng)計出的數(shù)據(jù)是求和還是最大值還是平均值等這就取決于SELECT后的聚合函數(shù))。因此要搞懂group by后帶rollup子句的用法主要是搞懂它是如何按一定的規(guī)則產(chǎn)生多種分組的group by帶rollup子句所返回的結(jié)果集,可以理解為各個分組所產(chǎn)生的結(jié)果集的并集且沒有去掉重復(fù)數(shù)據(jù)。下面舉例說明:

1、對比沒有帶rollup的goup by

例:Group by A ,B

產(chǎn)生的分組種數(shù):1種;

即group by A,B

返回結(jié)果集:也就是這一種分組的結(jié)果集。

2、帶rollup但group by與rollup之間沒有任何內(nèi)容

例1:Group by rollup(A ,B)

產(chǎn)生的分組種數(shù):3種;

第一種:group by A,B

第二種:group by A

第三種:group by NULL

(說明:本沒有group by NULL 的寫法,在這里指是為了方便說明,而采用之。含義是:沒有分組,也就是所有數(shù)據(jù)做一個統(tǒng)計。例如聚合函數(shù)是SUM的話,那就是對所有滿足條件的數(shù)據(jù)進行求和。此寫法的含義下同)

返回結(jié)果集:為以上三種分組統(tǒng)計結(jié)果集的并集且未去掉重復(fù)數(shù)據(jù)。

例2:Group by rollup(A ,B,C)

產(chǎn)生的分組種數(shù):4種;

第一種:group by A,B,C

第二種:group by A,B

第三種:group by A

第四種:group by NULL

返回結(jié)果集:為以上四種分組統(tǒng)計結(jié)果集的并集且未去掉重復(fù)數(shù)據(jù)。

3、帶rollup但group by與rollup之間還包含有列信息

例1:Group by A , rollup(A ,B)

產(chǎn)生的分組種數(shù):3種;

第一種:group by A,A,B    等價于group by A,B

第二種:group by A,A      等價于group by A

第三種:group by A,NULL  等價于group by A

返回結(jié)果集:為以上三種分組統(tǒng)計結(jié)果集的并集且未去掉重復(fù)數(shù)據(jù)。

例2:Group by C , rollup(A ,B)

產(chǎn)生的分組種數(shù):3種;

第一種:group by C,A,B    

第二種:group by C,A      

第三種:group by C,NULL  等價于group by C

返回結(jié)果集:為以上三種分組統(tǒng)計結(jié)果集的并集且未去掉重復(fù)數(shù)據(jù)。

4、帶rollup且rollup子句括號內(nèi)又使用括號對列進行組合

例1:Group by rollup((A ,B))

產(chǎn)生的分組種數(shù):2種;

第一種:group by A,B

第二種:group by NULL

返回結(jié)果集:為以上兩種分組統(tǒng)計結(jié)果集的并集且未去掉重復(fù)數(shù)據(jù)。

例2:Group by rollup(A ,(B,C))

產(chǎn)生的分組種數(shù):3種;

第一種:group by A,B,C

第二種:group by A

第三種:group by NULL

返回結(jié)果集:為以上三種分組統(tǒng)計結(jié)果集的并集且未去掉重復(fù)數(shù)據(jù)。

  注:對這種情況,可以理解為幾個列被括號括在一起時,就只能被看成一個整體,分組時不需要再細化。因此也可推斷rollup括號內(nèi)也頂多加到一重括號,加多重了應(yīng)該沒有任何意義(這個推斷我沒有做驗證的哦)。

二、與rollup組合使用的其它幾個輔助函數(shù)

1、grouping()函數(shù)

  必須接受一列且只能接受一列做為其參數(shù)。參數(shù)列值為空返回1,參數(shù)列值非空返回0。

2、grouping_id()函數(shù)

  必須接受一列或多列做為其參數(shù)。

返回值為按參數(shù)排列順序,依次對各個參數(shù)使用grouping()函數(shù),并將結(jié)果值依次串成一串二進制數(shù)然后再轉(zhuǎn)化為十進制所得到的值。

例如:grouping(A) = 0 ; grouping(B) = 1;

     則:grouping_id(A,B) = (01)2 = 1;

                    grouping_id(B,A) = (10)2 =2;

3、group_id()函數(shù)

  調(diào)用時不需要且不能傳入任何參數(shù)。

返回值為某個特定的分組出現(xiàn)的重復(fù)次數(shù)(第一大點中的第3種情況中往往會產(chǎn)生重復(fù)的分組)。重復(fù)次數(shù)從0開始,例如某個分組第一次出現(xiàn)則返回值為0,第二次出現(xiàn)時返回值為1,……,第n次出現(xiàn)返回值為n-1。

       注:使用以上三個函數(shù)往往是為了過濾掉一部分統(tǒng)計數(shù)據(jù),而達到美化統(tǒng)計結(jié)果的作用。

三、group by后帶rollup子句與group by后帶cube子句區(qū)別

group by后帶rollup子句與group by后帶cube子句的唯一區(qū)別就是:

帶cube子句的group by會產(chǎn)生更多的分組統(tǒng)計數(shù)據(jù)。cube后的列有多少種組合(注意組合是與順序無關(guān)的)就會有多少種分組。

例:Group by cube(A ,B,C)

產(chǎn)生的分組種數(shù):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

返回結(jié)果集:為以上八種分組統(tǒng)計結(jié)果集的并集且未去掉重復(fù)數(shù)據(jù)。

四、group by后帶grouping sets子句

   group by后帶grouping sets子句效果就是只返回小記記錄,即只返回按單個列分組后的統(tǒng)計數(shù)據(jù),不返回多個列組合分組的統(tǒng)計數(shù)據(jù)。

例1:Group by grouping sets(A )

產(chǎn)生的分組種數(shù):1種;

第一種:group by A

返回結(jié)果集:即為以上一種分組的統(tǒng)計結(jié)果集。

例2:Group by grouping sets(A ,B)

產(chǎn)生的分組種數(shù):2種;

第一種:group by A

第二種:group by B

返回結(jié)果集:為以上兩種分組統(tǒng)計結(jié)果集的并集且未去掉重復(fù)數(shù)據(jù)。

例3:Group by grouping sets (A ,B,C)

產(chǎn)生的分組種數(shù):3種;

第一種:group by A

第二種:group by B

第三種:group by C

返回結(jié)果集:為以上三種分組統(tǒng)計結(jié)果集的并集且未去掉重復(fù)數(shù)據(jù)。

select t.city_name,
       decode(t.directline_type,
              null,
              '總數(shù)',
              directline_type,
              directline_type),
       sum(t.amount)
from tmp_dl_info t
group by rollup(t.city_name, t.directline_type)