首先咱們建立一個示例表:函數
Create table test_group字體
(v_name varchar2(4)spa
,v_size varchar2(4)ci
,v_color varchar2(4)it
,n_num number(4)io
);table
--插入數據class
insert into test_grouptest
select '桌子','大','紅',10 from dual union all擴展
select '桌子','大','綠',10 from dual union all
select '桌子','小','紅',20 from dual union all
select '桌子','小','綠',40 from dual union all
select '椅子','大','紅',20 from dual union all
select '椅子','大','綠',30 from dual union all
select '椅子','小','紅',50 from dual union all
select '椅子','小','綠',100 from dual;
commit;
數據以下:
V_NAME |
V_SIZE |
V_COLOR |
N_NUM |
桌子 |
大 |
紅 |
10 |
桌子 |
大 |
綠 |
10 |
桌子 |
小 |
紅 |
20 |
桌子 |
小 |
綠 |
40 |
椅子 |
大 |
紅 |
20 |
椅子 |
大 |
綠 |
30 |
椅子 |
小 |
紅 |
50 |
椅子 |
小 |
綠 |
100 |
最簡單的分組(爲了初學者)
Select v_name,v_size,sum(n_num) as total_num
From test_group
group by v_name,v_size
V_NAME |
V_SIZE |
TOTAL_NUM |
椅子 |
大 |
50 |
桌子 |
小 |
60 |
椅子 |
小 |
150 |
桌子 |
大 |
20 |
使用rollup
rollup() 是group by()子句的一種擴展,能夠爲每一個分組返回小計記錄以及爲全部分組返回總計記錄
Select v_name,v_size,sum(n_num) as total_num
From test_group
group by rollup(v_name,v_size)
V_NAME | V_SIZE | TOTAL_NUM |
椅子 | 大 | 50 |
椅子 | 小 | 150 |
椅子 | 200 | |
桌子 | 大 | 20 |
桌子 | 小 | 60 |
桌子 | 80 | |
280 |
注意結果中
對各個型號,各個物品(不分顏色)進行統計,;
對各個物品(不分大小和顏色)進行統計(藍色底紋的數據)
對全部物品(不分類別,大小和顏色)進行總數量統計(綠色底紋的數據)
若是我想要全部大的物品(不區分椅子仍是桌子,也不區分顏色)統計數據怎麼辦?
能夠將group by rollup(v_name,v_size)變爲:group by rollup(v_size ,V_name)
那若是我即想要對全部物品類別進行統計還想要對大小進行統計怎麼辦?這時就須要用到cube
使用cube
cube() 也是group by()子句的一種擴展,能夠返回每個列組合的小計記錄(就是全部的維度都會進行統計),同時在末尾加上總計記錄.
Select v_name,v_size,sum(n_num) as total_num
From test_group
group by cube(v_name,v_size)
V_NAME |
V_SIZE |
TOTAL_NUM |
|
|
280 |
|
大 |
70 |
|
小 |
210 |
椅子 |
|
200 |
椅子 |
大 |
50 |
椅子 |
小 |
150 |
桌子 |
|
80 |
桌子 |
大 |
20 |
桌子 |
小 |
60 |
注意結果中
對各個型號,各個物品(不分顏色)進行分別統計;
對各個物品(不分大小和顏色)進行分別統計(藍色底紋的數據)
對各個型號(不分物品和顏色)進行分別統計(黃色底紋的數據)
對全部物品(不分類別,大小和顏色)進行統計(綠色底紋的數據)
那麼,如何能夠方便的區分結果中那個是小計,哪一個是合計呢?這時須要用到grouping_id()
使用grouping_id()
grouping_id()函數能夠接受一列或多列,返回grouping()位向量的十進制值
grouping()位向量的計算方法是將按照順序對每一列調用grouping()函數的結果組合起來
以grouping_id(v_name,v_size)爲例:
v_name ,v_size 位向量 grouping_id(v_name,v_size)
非空 非空 00 0
非空 空 01 1
空 非空 10 2
空 空 11 3
Select v_name,v_size,v_color,sum(n_num) as total_num,grouping_id(v_name,v_size,v_color) as grping_Id
From test_group
group by cube(v_name,v_size,v_color)
order by 1,2,3
V_NAME |
V_SIZE |
TOTAL_NUM |
GRPING_ID |
椅子 |
大 |
50 |
0 |
椅子 |
小 |
150 |
0 |
椅子 |
|
200 |
1 |
桌子 |
大 |
20 |
0 |
桌子 |
小 |
60 |
0 |
桌子 |
|
80 |
1 |
|
大 |
70 |
2 |
|
小 |
210 |
2 |
|
|
280 |
3 |
7.使用group_id()函數
使用group_Id()以前,咱們先分析一下下面的查詢結果:
Select v_name,v_size,sum(n_num) as total_num
From test_group
group by v_name,rollup(v_name,v_size)
V_NAME |
V_SIZE |
TOTAL_NUM |
椅子 |
大 |
50 |
椅子 |
小 |
150 |
桌子 |
大 |
20 |
桌子 |
小 |
60 |
椅子 |
|
200 |
桌子 |
|
80 |
椅子 |
|
200 |
桌子 |
|
80 |
和group by rollup(v_name,v_size) 相比結果集中多了兩組重複的數據,少了總計.
多出來的數據是怎麼來的呢?期實是由總計演化而來的,演化的過程以下:
首先能夠將語句
Select v_name,v_size,sum(n_num) as total_num
From test_group
group by v_name,rollup(v_name,v_size)
進行分解:
Select v_name,v_size,sum(n_num) as total_num
From test_group
where v_name='椅子'
group by rollup(v_name,v_size)
Select v_name,v_size,sum(n_num) as total_num
From test_group
where v_name='桌子'
group by rollup(v_name,v_size)
由於這裏只有’椅子’,’桌子’兩種物品.
結果分別以下:
V_NAME |
V_SIZE |
TOTAL_NUM |
椅子 |
大 |
50 |
椅子 |
小 |
150 |
椅子 |
|
200 |
椅子 |
|
200 |
V_NAME |
V_SIZE |
TOTAL_NUM |
桌子 |
大 |
20 |
桌子 |
小 |
60 |
桌子 |
|
80 |
桌子 |
|
80 |
這是兩個使用rollup的查詢結果,裏面的總計部分期初和小計部分的數據是相同的,由於只計也只是包含椅子(或桌子)的數據. 因此這裏能夠用椅子(或桌子)來填充總計的空白處(表格中的黃色字體部分).而後將這兩個表格的數據合併在一塊兒,就能夠獲得
group by v_name,rollup(v_name,v_size) 的結果了.
那咱們如何來區分這兩組相同的數據呢?這時就能夠用到group_id()函數了.
以下:
Select v_name,v_size,sum(n_num) as total_num
,grouping_id(v_name,v_size) as gping_id
,group_Id() as gp_id
From test_group
group by v_name,rollup(v_name,v_size)
V_NAME |
V_SIZE |
TOTAL_NUM |
GPING_ID |
GP_ID |
椅子 |
大 |
50 |
0 |
0 |
椅子 |
小 |
150 |
0 |
0 |
桌子 |
大 |
20 |
0 |
0 |
桌子 |
小 |
60 |
0 |
0 |
椅子 |
|
200 |
1 |
0 |
桌子 |
|
80 |
1 |
0 |
椅子 |
|
200 |
1 |
1 |
桌子 |
|
80 |
1 |
1 |
爲了進行區分這裏一併加上了grouping_id,注意觀察grouping_id()和group_Id()的區別.