group by、rollup、cube的用法以及區別


 在此使用oracle,oracle 中的用法為 group by [rollup|cube]( colomn),sql server中的用法為group by colomn with [rollup|cube]

  首先要弄明白rollup 和cube,就要知道group by的用法,group by 為對列進行分組,只展現分組統計的值,而rollup 為分層次展現,cube為展現列中所有層次,聽我娓娓道來。

1、搭建場地

首先建立一個group_by 表,列值分別為購買者名稱,購買物品的大類,購買物品的小類,物品以及價格,

用戶購買了一些3C以及衣物

 1 create table group_by (
 2 o_name varchar2(20),
 3 o_class varchar2(20),
 4 o_item varchar2(20),
 5 o_object varchar2(20),
 6 o_price int
 7 )
 8 
 9 insert into group_by values('springy','3C','phone','huawei',4000);
10 insert into group_by values('springy','3C','phone','xiaomi',3000);
11 insert into group_by values('springy','3C','computer','mac',10000);
12 insert into group_by values('springy','3C','phone','thinkpad',8000);
13 insert into group_by values('springy','3C','phone','huawei',4000);
14 insert into group_by values('springy','clothes','shoes','adidas',300);
15 insert into group_by values('springy','clothes','shoes','lining',400);
16 insert into group_by values('springy','clothes','pants','jackjones',500);
17 insert into group_by values('stephenson','clothes','shoes','adivon',200);
18 insert into group_by values('stephenson','clothes','shoes','nike',300);
19 insert into group_by values('stephenson','clothes','skirt','nike',300);
20 insert into group_by values('stephenson','clothes','skirt','adidas',400);
21 commit;
View Code

2、初識group by

此時向我們緩緩走來的是group by,group by 可以對數據進行分組求值。

首先對O_NAME,O_CLASS,O_ITEM進行group by 分組 ,查看購買者購買對應分類物品的價格合計。

1 select o_name, o_class, o_item, sum(o_price)
2 from group_by
3 group by o_name, o_class, o_item
4 order by o_name, o_class, o_item
View Code

我們可以看到購買者沒類物品消耗的價格

3、rollup

此時我們對統計的數據不太理想,除了想看每個小類,還想看每個大類,以及他們兩人的消費和

表格畫出來就是這個意思

    表3-1

這時,我們將其與上面group by的進行對比,發現多了這些

    表3-2

而這些又是怎么出來的呢?

這是就回到了開始所說的,rollup為分層次展現,怎么個分層次法呢?

首先,我們要確定,group by 的為O_NAME,O_CLASS,O_ITEM,此時對這些值進行分層次展現,即為下表

其中第一行為group by出來的,接下來的三行即為分層次匯總統計,而最后的空白的一行為對購買者進行匯總統計。

帶入我們的例子中,可以看出來即為表3-1,而第2-4行則為多出來的部分,在此也可以看出來rollup 對group by中的值有順序要求

1 select o_name,o_class,o_item,sum(o_price),grouping(o_name ),grouping(o_class),grouping(o_item)
2 from group_by
3 group by rollup (o_name,o_class,o_item) 
4 order by o_name,o_class,o_item 
View Code

使用rollup出來的結果

此時,看到的結果和表格也不一樣呀,其中還有這么多空格怎么處理??別急,接下來會講到

4、初始cube 

說完rollup,開始說cube

開始說cube為展現所有層次,這是什么意思呢?就是有這里面所有的分組匯總統計

 在此,看下我們的結果

select o_name,o_class,o_item,sum(o_price),grouping(o_name ),grouping(o_class),grouping(o_item)
from group_by
group by cube (o_name,o_class,o_item) 
order by o_name,o_class,o_item 
View Code

 

5、group by、rollup、cube的用法以及區別

cube的組合

使用數字表達一下,看上去至少會更清晰點

想必這樣子看上去更明白些,空值部分即該行為合計,這里面列出了所有分組。

而cube與rollup的區別在於后面對2,3部分的分組

rollup分組

group by分組

想必這樣子更直觀

 6、處理空值

此時有一個方法為grouping() 可以查看該值是否有rollup|cube產生的,若為其值則為1,否則為0,使用一個case when判斷一下就好。

下圖為使用cube時,可以看出每個有cube產生合計,即空值處,其grouping的值都為1

1 select o_name,o_class,o_item,sum(o_price),grouping(o_name ),grouping(o_class),grouping(o_item)
2 from group_by
3 group by cube (o_name,o_class,o_item) 
4 order by o_name,o_class,o_item 
View Code

 

7 應用

7.1在統計時,若只有一列,那么cube和rollup沒差別

select case
         when grouping(o_name) = '1' then
          '合計'
         else
          o_name
       end as customer,
       sum(o_price) as total,
       grouping(o_name) 
  from group_by
 group by rollup(o_name)
 order by o_name
View Code

 

在看到上圖時,只對一列進行統計時,並且有合計值時使用cube和rollup都ok。

7.2 若進行兩列的統計

 1 select case
 2          when grouping(o_name) = '1' then
 3           count(distinct o_name) || ''
 4          else
 5           o_name
 6        end as customer,
 7        case
 8          when grouping(o_class) = 1 and grouping(o_name) = 1 then
 9           '合計'
10          when grouping(o_class) = 1 then
11           '小計'
12          else
13           o_class
14        end as class,
15        sum(o_price) as total,
16        grouping(o_name),
17        grouping(o_class)
18   from group_by
19  group by rollup(o_name, o_class)
20  order by o_name, o_class
View Code

看到類似上圖時,總的合計中不出現第二列的詳細情況時,只對兩列進行總的合計時,使用rollup

7.3 兩列分各種情況全統計

 此時,我除了想看到兩位顧客和消費,還想看到兩位在各個類上的消費是

 1 select case
 2          when grouping(o_name) = '1' and grouping(o_class) = 1 then
 3           count(distinct o_name) || '位消費'
 4            when grouping(o_class) = 1
 5          then
 6           o_name
 7        end as customer,
 8        case
 9          when grouping(o_class) = 1 and grouping(o_name) = 1 then
10           '合計'
11          when grouping(o_class) = 1 then
12           '小計'
13          else
14           o_class
15        end as class,
16        sum(o_price) as total,
17        grouping(o_name),
18        grouping(o_class)
19   from group_by
20  group by cube(o_name, o_class)
21  order by o_name, o_class desc
View Code

 

對應的圖就是上面這樣子。

若果仍不清楚,就挨着試一下rollup和cube。

 


免責聲明!

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



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