[转]详解Oracle高级分组函数(ROLLUP, CUBE, GROUPING SETS)
原文地址:http://blog.csdn.net/u014558001/article/details/42387929
本文主要講解 ROLLUP, CUBE, GROUPING SETS的主要用法,這些函數(shù)可以理解為GroupBy分組函數(shù)封裝后的精簡用法,相當于多個union all 的組合顯示效果,但是要比 多個union all的效率要高。
其實這些函數(shù)在時間的程序開發(fā)中應用的并不多,至少在我工作的多年時間中沒用過幾次,因為現(xiàn)在的各種開發(fā)工具/平臺都自帶了這些高級分組統(tǒng)計功能,使用的方便性及美觀性都比這些要好。但如果臨時查下數(shù)據(jù),用這些函數(shù)還是不錯的。
創(chuàng)建測試環(huán)境
1.????? 創(chuàng)建表
?
[sql] view plain copy?
2.????? 插入測試數(shù)據(jù)
?
[sql] view plain copy?
?
3.???? 查看一下剛才插入的數(shù)據(jù)
?
[sql] view plain copy?
?
?
4.????? 先看下普通分組的效果
按照地區(qū)統(tǒng)計每個部門的總工資
[sql] view plain copy查看結(jié)果如下:
?
?
ROLLUP(累計累加)
ROLLUP是對group by的擴展,因此,它只能出現(xiàn)在group by子句中,依賴于分組的列,對每個分組會生成匯總數(shù)據(jù), rollup和group by聯(lián)合一起使用,達到了按group by列順序分組,并且實現(xiàn)小計和合計的功能。rollup分組還是有序的,先全部分組,然后對每個分組小計,最后合計。
rollup中列的順序不同,則統(tǒng)計的結(jié)果不同。因為它是按列從右遞減分組的。
比如 Group by? ROLLUP(A, B, C),首先會對(A、B、C)進行GROUP BY,然后對(A、B)進行GROUP BY,然后是(A)進行GROUP BY,最后對全表進行GROUP BY操作
?
按照地區(qū)統(tǒng)計每個部門的總工資,按工作母地匯總,再合計
?
[sql] view plain copy?
?
?
結(jié)果相當于
?
[sql] view plain copy?
?
?
如果顛倒下rollup順序則結(jié)果如下:
[sql] view plain copy?
?
如果在實際查詢中,有的小計或合計我們不需要,那么就要使用局部rollup,局部rollup就是將需要固定統(tǒng)計的列放在group by中,而不是放在rollup中。
?
?
[sql] view plain copy?
與group by rollup(dept,base)相比:去掉了最后一行的匯總,因為每次匯總要么是dept,base,要么是dept,null ,dept是固定的。
?
?
如果只希望看到合計則可以這樣寫:
?
[sql] view plain copy?
?
?
?
?
CUBE(交叉列表)
CUBE也是對group by運算的一種擴展,它比rollup擴展更加精細,組合類型更多,rollup是按組合的列從右到左遞減分組計算,而CUBE則是對所有可能的組合情況進行分組,這樣分組的情況更多,覆蓋所有的可能分組,并計算所有可能的分組的小計。
?
對于CUBE來說,列的名字只要一樣,那么順序無所謂,結(jié)果都是一樣的,因為cube是各種可能情況的組合,只不過統(tǒng)計的結(jié)果順序不同而已。但是對于rollup來說,列的順序不同,則結(jié)果不同。
?
?
比如對工作母地和部門的交叉統(tǒng)計
[sql] view plain copy?
?
?
部分CUBE和部分ROLLUP類似,把需要固定統(tǒng)計的列放到group by中,不放到cube中就可以了。
如果cube中只有一個列,那么和rollup的結(jié)果一致
?
?
[sql] view plain copy?
?
?
rollup和cube區(qū)別:
如果是ROLLUP(A,B, C)的話,GROUP BY順序
(A、B、C)
(A、B)
(A)
最后對全表進行GROUPBY操作。
如果是GROUP BY CUBE(A, B, C),GROUP BY順序
(A、B、C)
(A、B)
(A、C)
(A),
(B、C)
(B)
(C),
最后對全表進行GROUPBY操作。
?
GROUPING SETS
對group by的另一個擴展,專門對分組列分別進行小計計算,不包括合計。使用方式和rollup和cube一樣,都是放在group by中。
??
比如需要分別統(tǒng)計工作母地與部門的合計:
?
[sql] view plain copy結(jié)果為:
?
等價于
?
[sql] view plain copy?
?
理解了groupingsets的原理我們用他實現(xiàn)rollup的功能也是可以的:
?
[sql] view plain copy?
效果如下:
?
?
?
?
grouping函數(shù)
在以上例子中,是用rollup和cube函數(shù)都會對結(jié)果集產(chǎn)生null,這時候可用grouping函數(shù)來確認該記錄是由哪個字段得出來的
grouping函數(shù)用法,帶一個參數(shù),參數(shù)為字段名,結(jié)果是根據(jù)該字段得出來的就返回1,反之返回0
例如:
?
[sql] view plain copy?
?
?
?
更多ROLLUP,CUBE, GROUPING SETS與GROUP BY的關(guān)系可以參考Oracle官方文檔中的例子
?
http://docs.oracle.com/cd/E11882_01/server.112/e25554/aggreg.htm#DWHSG8608
總結(jié)
以上是生活随笔為你收集整理的[转]详解Oracle高级分组函数(ROLLUP, CUBE, GROUPING SETS)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: T-SQL查询高级—SQL Server
- 下一篇: webservice axis1.4生成