【CUBE】Oracle分組函式之CUBE魅力

kingsql發表於2015-05-02
  Oracle的CUBE與ROLLUP功能很相似,也是在資料統計分析領域的一把好手。
  關於ROLLUP的查詢統計功能請參考文章《【ROLLUP】Oracle分組函式之ROLLUP魅力》(http://space.itpub.net/519536/viewspace-610995)。

1.先看一下ROLLUP的資料統計效果
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.

4)ROLLUP的資料統計效果
sec@ora10g> 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.

2.進一步體驗CUBE的魅力
sec@ora10g> select group_id,job,grouping(GROUP_ID),grouping(JOB),sum(salary) from group_test group by cube(group_id, job) order by 1;

  GROUP_ID JOB        GROUPING(GROUP_ID) GROUPING(JOB) SUM(SALARY)
---------- ---------- ------------------ ------------- -----------
        10 Architect                   0             0        1000
        10 Coding                      0             0        1000
        10 Director                    0             0        1000
        10 Programmer                  0             0        1000
        10                             0             1        4000
        20 Architect                   0             0        2000
        20 Coding                      0             0        2000
        20 Director                    0             0        2000
        20 Programmer                  0             0        2000
        20                             0             1        8000
        30 Architect                   0             0        3000
        30 Coding                      0             0        3000
        30 Director                    0             0        3000
        30 Programmer                  0             0        3000
        30                             0             1       12000
        40 Architect                   0             0        4000
        40 Coding                      0             0        4000
        40 Director                    0             0        4000
        40 Programmer                  0             0        4000
        40                             0             1       16000
           Architect                   1             0       10000
           Coding                      1             0       10000
           Director                    1             0       10000
           Programmer                  1             0       10000
                                       1             1       40000

25 rows selected.

  解釋如上結果中GROUPING函式返回值“0”和“1”的含義。
  如果顯示“1”表示CUBE函式對應的列(例如JOB欄位)是由於CUBE函式所產生的空值對應的資訊,即對此列進行彙總計算後的結果。
  如果顯示“0”表示此行對應的這列參未與ROLLUP函式分組彙總活動。
  如果還是沒有理解清楚,請參見Oracle官方文件中的描述內容:“Using a single column as its argument,GROUPINGreturns 1 when it encounters aNULLvalue created by aROLLUPorCUBEoperation. That is, if theNULLindicates the row is a subtotal,GROUPINGreturns a 1. Any other type of value, including a storedNULL, returns a 0.”

3.仔細觀察一下,CUBE與ROLLUP之間的細微差別
rollup(a,b)   統計列包含:(a,b)、(a)、()
rollup(a,b,c) 統計列包含:(a,b,c)、(a,b)、(a)、()
……以此類推ing……

cube(a,b)     統計列包含:(a,b)、(a)、(b)、()
cube(a,b,c)   統計列包含:(a,b,c)、(a,b)、(a,c)、(b,c)、(a)、(b)、(c)、()
……以此類推ing……

So,上面例子中CUBE的結果比ROLLUP多了下面關於第一列GROUP_ID的統計資訊:
           Architect                   1             0       10000
           Coding                      1             0       10000
           Director                    1             0       10000

4.小結
  CUBE在ROLLUP的基礎上進一步從各種維度上給出細化的統計彙總結果。
  CUBE與GROUP BY的關係可以參考Oracle官方文件中的例子,連結如下:,連結如下:《CUBE Extension to GROUP BY》

Good luck.

secooler
12.04.23

-- The End --

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28389881/viewspace-1617739/,如需轉載,請註明出處,否則將追究法律責任。

相關文章