/*************************************************
主題:擴展 GROUP BY 編碼
CUBE ,ROLLUP,GROUPING SETS,GROUPING_ID,GROUP_ID
*************************************************/code
1.ROLLUP ,按列的順序從右到左遞減分組小計(含合計)
-------------------------------------
從右到左遞減分組
統計級別 : SGNYEAR,AREACODE --1
SGNYEAR --2
NULL(合計) --3
-------------------------------------
SELECT SGNYEAR,AREACODE,SUM(CARGOVOLUME) S
FROM TEST3
WHERE SGNYEAR BETWEEN '2002' AND '2004'
GROUP BY ROLLUP(SGNYEAR,AREACODE) ;
SGNYEAR AREACODE S
--------- --------------------- ----------
2002 150000 37239
2002 230000 12919
2002 330000 2327
2002 360000 0 --年的某個AREACODE 小計
2002 52485 --年小計
2003 130000 1486
2003 440000 73087
2003 640000 0
2003 74573
2004 410000 0
2004 0
127058 --總計
--------- --------------------- ---------- 擴展
2.ROLLUP部分分組, 分組剔除某些字段來的小計(不含合計)
SELECT SGNYEAR,AREACODE,SUM(CARGOVOLUME) S
FROM TEST3
WHERE SGNYEAR BETWEEN '2002' AND '2004'
GROUP BY SGNYEAR ,ROLLUP(AREACODE);--根據年分組,剔除AREARCODE的分組小計 與 總體的合計二進制
SGNYEAR AREACODE S
--------- --------------------- ----------
2002 150000 37239
2002 230000 12919
2002 330000 2327
2002 360000 0
2002 52485
2003 130000 1486
2003 440000 73087
2003 640000 0
2003 74573
2004 410000 0
2004 0
--------- --------------------- ----------
3.CUBE,對不一樣維度的全部可能分組進行統計(各類可能性分組)
SELECT SGNYEAR,AREACODE,SUM(CARGOVOLUME) S
FROM TEST3
WHERE SGNYEAR BETWEEN '2002' AND '2004'
GROUP BY CUBE(SGNYEAR,AREACODE) ;
SGNYEAR AREACODE S
--------- --------------------- ----------
127058 --總計
130000 1486 --AREACODE的小計
150000 37239
230000 12919
330000 2327
360000 0
410000 0
440000 73087
640000 0
2002 52485 --SGNYEAR的小計
2002 150000 37239 --SGNYEAR,AREACODE的小計
2002 230000 12919
2002 330000 2327
2002 360000 0
2003 74573
2003 130000 1486
2003 440000 73087
2003 640000 0
2004 0
2004 410000 0
--------- --------------------- ---------- 統計
4.CUBE 部分分組
SELECT SGNYEAR,AREACODE,SUM(CARGOVOLUME) S
FROM TEST3
WHERE SGNYEAR BETWEEN '2002' AND '2004'
GROUP BY SGNYEAR,CUBE(AREACODE) ; --剔除對AREACODE的分組小計 與 總體的合計數據
SGNYEAR AREACODE S
--------- --------------------- ----------
2002 52485
2002 150000 37239
2002 230000 12919
2002 330000 2327
2002 360000 0
2003 74573
2003 130000 1486
2003 440000 73087
2003 640000 0
2004 0
2004 410000 0
--------- --------------------- ----------項目
5.GROUPING SETS 實現小計,沒有合計
SELECT SGNYEAR,AREACODE,SUM(CARGOVOLUME) S
FROM TEST3
WHERE SGNYEAR BETWEEN '2002' AND '2004'
GROUP BY GROUPING SETS(SGNYEAR,AREACODE) ; --對SGNYEAR,AREACODE分別進行小計統計
SGNYEAR AREACODE S
--------- --------------------- ----------
2004 0
2002 52485
2003 74573
410000 0
330000 2327
640000 0
360000 0
150000 37239
230000 12919
440000 73087
130000 1486
--------- --------------------- ---------- co
6.GROUPING SETS 部分統計.對單列進行分組,統計其餘維度的小計。
SELECT SGNYEAR,AREACODE,transtypecode,SUM(CARGOVOLUME) S
FROM TEST3
WHERE SGNYEAR BETWEEN '2002' AND '2005'
GROUP BY SGNYEAR,GROUPING SETS(AREACODE,transtypecode) ; --統計每一年,每一個AREACODE 的小計
--統計每一年,每一個TRANSTYPECODE 的小計
SGNYEAR AREACODE TRANSTYPECODE S
--------- --------------------- --------------------- ----------
2002 360000 0
2003 130000 1486
2003 640000 0
2002 330000 2327
2002 230000 12919
2004 410000 0
2003 440000 73087
2005 140000 47697
2005 620000 4085
2002 150000 37239
2002 3 15246
2002 5 0
2002 6 37239
2004 5 0
2005 3 47697
2005 2 4085
2003 7 0
2003 4 1486
2003 6 73087
--------- --------------------- --------------------- ----------
7.CUBE、ROLLUP 做爲 GROUPING SETS 的參數,至關於對每一個 CUBE 或 ROLLUP 的操做 UNION ALL
SELECT AREACODE,transtypecode,SUM(CARGOVOLUME) S
FROM TEST3
WHERE SGNYEAR BETWEEN '2002' AND '2005'
GROUP BY GROUPING SETS(CUBE(AREACODE),ROLLUP(transtypecode));
AREACODE TRANSTYPECODE S
--------------------- --------------------- ----------
130000 1486
140000 47697
150000 37239
230000 12919
330000 2327
360000 0
410000 0
440000 73087
620000 4085
640000 0
6 110326
2 4085
4 1486
3 62943
5 0
7 0
178840 --此處兩個數據就是ROLLUP的UNION ALL
178840
--------------------- --------------------- ----------
8.組合列分組360
列 獲得結果的描述
--------------------- --------------------- ----------
ROLLUP(a,b,c) GROUP BY a,b,c
GROUP BY a,b
GROUP BY a
GROUP BY NULL
--------------------- --------------------- ----------
ROLLUP(a,(b,c)) GROUP BY a,b,c
GROUP BY a --此處將(b,c)看作一列,因此縮減了
GROUP BY NULL
--------------------- --------------------- ----------
--根據年進行分組,獲得標準的分組統計
--獲得 年的小計 ,與標準ROLLUP對比,少了年+編碼的小計
SELECT SGNYEAR,AREACODE,transtypecode,SUM(CARGOVOLUME) S
FROM TEST3
WHERE SGNYEAR BETWEEN '2002' AND '2006'
GROUP BY ROLLUP(SGNYEAR,(AREACODE,transtypecode)) ;
SGNYEAR AREACODE TRANSTYPECODE S
--------- --------------------- --------------------- ----------
2002 150000 6 37239
2002 230000 3 12919 --年份、類型同
2002 330000 3 2327 --編碼不一樣
2002 360000 5 0
2002 52485
2003 130000 4 1486
2003 440000 6 73087
2003 640000 7 0
2003 74573
2004 410000 5 0
2004 0
2005 140000 3 47697
2005 620000 2 4085
2005 51782
2006 120000 5 0
2006 140000 7 59
2006 350000 5 910
2006 500000 3 2000
2006 530000 5 171
2006 3140
--------- --------------------- --------------------- ----------
9.鏈接分組,容許 GROUP BY 後面有多個 ROLLUP、CUBE、GROUPING SETS,結果是分級別組成的笛卡爾積參數
SELECT SGNYEAR,AREACODE,transtypecode,SUM(CARGOVOLUME) S
FROM TEST3
WHERE SGNYEAR BETWEEN '2002' AND '2003'
GROUP BY ROLLUP(AREACODE,transtypecode) ,ROLLUP(SGNYEAR);
SGNYEAR AREACODE TRANSTYPECODE S
--------- --------------------- --------------------- ----------
130000 4 1486
130000 1486
150000 6 37239
150000 37239
230000 3 12919
230000 12919
330000 3 2327
330000 2327
360000 5 0
360000 0
440000 6 73087
440000 73087
640000 7 0
640000 0
127058
2002 150000 6 37239
2002 150000 37239
2002 230000 3 12919
2002 230000 12919
2002 330000 3 2327
2002 330000 2327
2002 360000 5 0
2002 360000 0
2002 52485
2003 130000 4 1486
2003 130000 1486
2003 440000 6 73087
2003 440000 73087
2003 640000 7 0
2003 640000 0
2003 74573
--------- --------------------- --------------------- ----------
10.重複列分組
SELECT SGNYEAR,AREACODE,transtypecode,SUM(CARGOVOLUME) S
FROM TEST3
WHERE SGNYEAR BETWEEN '2002' AND '2003'
GROUP BY AREACODE,ROLLUP(AREACODE,transtypecode) ,ROLLUP(SGNYEAR);
--獲得的數據 AREACODE 的小計重複出現
CUBE(A,B,C)==ROLLUP(A),ROLLUP(B),ROLLUP(C)
11.GROUPING,對於小計或合計的列返回1,不然返回0.
SELECT SGNYEAR,AREACODE,SUM(CARGOVOLUME) S,GROUPING(AREACODE),
DECODE(GROUPING(AREACODE),1,'小計',NVL(AREACODE,'合計')) ITEM
FROM TEST3
WHERE SGNYEAR BETWEEN '2002' AND '2006'
GROUP BY ROLLUP(SGNYEAR,AREACODE) ;
SGNYEAR AREACODE S GROUPING(AREACODE) ITEM
--------- --------------------- ---------- ------------------ ---------------
2002 150000 37239 0 150000
2002 230000 12919 0 230000
2002 330000 2327 0 330000
2002 360000 0 0 360000
2002 52485 1 小計
2003 130000 1486 0 130000
2003 440000 73087 0 440000
2003 640000 0 0 640000
2003 74573 1 小計
2004 410000 0 0 410000
2004 0 1 小計
2005 140000 47697 0 140000
2005 620000 4085 0 620000
2005 51782 1 小計
2006 120000 0 0 120000
2006 140000 59 0 140000
2006 350000 910 0 350000
2006 500000 2000 0 500000
2006 530000 171 0 530000
2006 3140 1 小計
181980 1 小計
--------- --------------------- ---------- ------------------ ---------------
--過濾某些分組結果
SELECT SGNYEAR,AREACODE,SUM(CARGOVOLUME) S,DECODE(GROUPING(AREACODE),1,'小計',NVL(AREACODE,'合計')) ITEM
FROM TEST3
WHERE SGNYEAR BETWEEN '2002' AND '2006'
GROUP BY ROLLUP(SGNYEAR,AREACODE)
HAVING GROUPING(SGNYEAR)=1 OR GROUPING(AREACODE)=0;
12.GROUPING_ID,對多列進行計算,獲得分組級別
分組 位向量(二進制) GROUPING_ID結果(根據二進制獲得的十進制數)
-------- --------- --------------
A,B,C 000 0
A,B 001 1
A 011 3
NULL 111 7
SELECT SGNYEAR,AREACODE,SUM(CARGOVOLUME) S,GROUPING(AREACODE) YorN,
GROUPING_ID(SGNYEAR,AREACODE) ORDERS
FROM TEST3
WHERE SGNYEAR BETWEEN '2002' AND '2006'
GROUP BY ROLLUP(SGNYEAR,AREACODE) --括號內的內容保持一致
HAVING GROUPING_ID(SGNYEAR,AREACODE) IN (0,3); --括號內的內容保持一致,可是能夠改變順序來到達某些統計目的
SGNYEAR AREACODE S YORN ORDERS
--------- --------------------- ---------- ---------- ----------
2002 150000 37239 0 0
2002 230000 12919 0 0
2002 330000 2327 0 0
2002 360000 0 0 0
2003 130000 1486 0 0
2003 440000 73087 0 0
2003 640000 0 0 0
2004 410000 0 0 0
2005 140000 47697 0 0
2005 620000 4085 0 0
2006 120000 0 0 0
2006 140000 59 0 0
2006 350000 910 0 0
2006 500000 2000 0 0
2006 530000 171 0 0
181980 1 3
--------- --------------------- ---------- ---------- ----------
SELECT SGNYEAR,AREACODE,SUM(CARGOVOLUME) S,GROUPING(AREACODE) YorN,
GROUPING_ID(SGNYEAR,AREACODE) ORDERS
FROM TEST3
WHERE SGNYEAR BETWEEN '2002' AND '2006'
GROUP BY ROLLUP(SGNYEAR,AREACODE)
HAVING GROUPING_ID(AREACODE,SGNYEAR) IN (0,1);
13.GROUP_ID , 區分重複分組的結果,第一次出現爲 0,後面每次+1.
SELECT SGNYEAR,AREACODE,transtypecode,SUM(CARGOVOLUME) S,GROUP_ID() GI,
GROUPING_ID(AREACODE,transtypecode,SGNYEAR) LV
FROM TEST3
WHERE SGNYEAR BETWEEN '2002' AND '2003'
GROUP BY ROLLUP(AREACODE,transtypecode,SGNYEAR) ,ROLLUP(SGNYEAR)
HAVING GROUP_ID()=0;
14.應用
SELECT SYMBOL,ENDDATE,ITEM,SUM(AMOUNT) ,GROUPING_ID(SYMBOL,ENDDATE,ITEM) LV,
DECODE(GROUPING_ID(SYMBOL,ENDDATE,ITEM) ,3,'公司總計',0 ,'標準小計',7,'總合計',1,'公司年合計') LVNAME,
GROUP_ID() GI
FROM INPUT.TBL_CHN_I_Notes_AdminExpense
GROUP BY ROLLUP(SYMBOL,ENDDATE,ITEM)
--HAVING GROUPING_ID(SYMBOL,ENDDATE,ITEM) IN (0,3,7)
ORDER BY SYMBOL,ENDDATE,ITEM;
--
SELECT SYMBOL,ENDDATE,ITEM,SUM(AMOUNT)--求每一個公司每一年,橫跨項目計費用
FROM INPUT.TBL_CHN_I_Notes_AdminExpense
GROUP BY SYMBOL,ENDDATE,ROLLUP(ITEM)
--