1、rollup和cube函式,自動彙總資料
select * from test_tbl的資料這樣的
col_a col_b col_c
---- ----- -----
1
b1 12
1
b1 2
1
b2 31
2
b2 7
2
b3 42
2
b3 1
2
b3 3
如果按a、b列進行彙總c列,用一般的方法是這樣:
select col_a,col_b,sum(col_c) from
test_tbl group by col_a,col_b 結果如下
col_a col_b sum(col_c)
---- ----- --------
1
b1 14
1
b2 31
2
b2 7
2
b3 46
但是如果這時候還想按a列彙總且要c列的合計數,那就要再用兩個sql來巢狀,很麻煩,不過用
rollup就簡單多了:
select nvl(col_a,'合計')
col_a,nvl(col_b,decode(col_a,null,'','小計'||col_a))
col_b,sum(col_c)
from test_tbl group by
rollup(col_a,col_b),結果如下
col_a col_b sum(col_c)
---- ----- --------
1
b1 14
1
b2 31
1 小計1
452
b2 7
2
b3 46
2 小計2
53合計 98
結果集剛好是先按a和b彙總,然後是按a彙總,最後是全部彙總這時候如果再要按b列彙總,怎麼辦
呢?又要用sql巢狀嗎?不是的,如果有這要求的話,改用cube函式就ok啦
select
nvl(col_a,decode(col_b,null,'合計','小計'||col_b))
col_a,nvl(col_b,decode
(col_a,null,'','小計'||col_a)) col_b,sum(col_c)
from test_tbl group by cube(col_a,col_b)
結果如下
col_a col_b sum(col_c)
---- ----- --------
1
b1 14
1
b2 31
1 小計1
452
b2 7
2
b3 46
2 小計2
53小計b1 b1 14
小計b2 b2 38
小計b3 b3 46
合計 98
跟剛才rollup函式得到的結果集有點不一樣,那就是多了些按b列的彙總行。
2、lag和lead函式,自動鏈結上/下行記錄值
sql> desc
test_tbl
name type
----- ------
col_k number
現在按順序的往這個test_tbl表中插入一系列資料,下面是sql:
insert into test_tbl values(1)
insert into test_tbl values(2)
insert into test_tbl values(4)
insert into test_tbl values(5)
insert into test_tbl values(8)
insert into test_tbl values(9)
insert into test_tbl values(11)
insert into test_tbl values(12)
insert into test_tbl values(13)
........
資料插完後,要檢查插入的資料中,從最小數到最大數之間有那些數是沒被插入表,找出這些數的
前乙個和後乙個數?如這個例裡從1到13當中有目字3、6、7、10沒被插入表中,這些數的前乙個和後一
個分別是2和4、5和8、9和11,即
prev_val next_val
---------- ----------
2 45 8
9 11
如果不用分析函式要得到這後結果集那真不敢想象是怎麼樣的一段sql,但用lag分析函式那就簡單
了,這樣寫就ok
select prev_val,next_val from(
select col_k next_val,lag(col_k,1,0) over
(order by col_k) prev_val from test_tbl
) where
next_val-prev_val>1
對於lead函式是一樣的,只不過它是往後鏈結而已。
3、rank和dense_rank函式,對資料進行排名
測試表是這樣的select *from
test_tbl結集如下
col_a col_b
---------- ----------
a 242
a 233
b 154
c 287
c 76
d 66
e 154
f 154
g 212
g 43
按a列來統計b列的值,用一般的sql是這樣select col_a,
sum(col_b) from test_tbl group by
col_a order by 2 desc 結果是這樣
col_a sum(col_b)
---------- ----------
a 475
c 363
g 255
b 154
f 154
e 154
d 66
從這個資料集可以看出a是最大的,c是第二大的,當資料多時就不知道誰是排第幾了,這時用
dense_rank可以達到這目的
select col_a,sum(col_b),dense_rank() over
(order by sum(col_b) desc) ranks from
test_tbl group by col_a 結果如下
col_a sum(col_b) ranks
---------- ---------- ----------
a 475 1
c 363 2
g 255 3
b 154 4
f 154 4
e 154 4
d 66 5
這個資料集把每個值都排了名次,可以直接看得出,相同值的名次是相同的。
用rank跟dense_rank差不多,不過就是當出現在名次相同時,下乙個名次會跳躍
select col_a,sum(col_b),rank() over (order
by sum(col_b) desc ) ranks from test_tbl
group by col_a 結果如下
col_a sum(col_b) ranks
---------- ---------- ----------
a 475 1
c 363 2
g 255 3
b 154 4
f 154 4
e 154 4
d 66 7
可以看到名次從4跳躍到7,就是因為名次4重複出現了兩次
實際應用中可能會比這些例子要複雜多點,可能會先對錶的資料分組,然後再用分析,如
select *from test_tbl的結果是這樣的
col_g col_a col_b
---------- ---------- ----------
g1 a 242
g1 a 233
g2 c 287
g2 c 76
g2 d 66
g2 e 154
g3 f 154
g3 g 212
g3 g 43
g2 b 154
對這個資料集按g和a列彙總b列進行排名,就要先對表按g列進行分組,然後再按a列彙總b列值進行
排名select col_g,col_a,sum(col_b),dense_rank()
over (partition by col_g order by sum
(col_b) desc ) ranks
from test_tbl
group by col_g,col_a這個sql加了partition
by先按g列分組,結果如下
col_g col_a sum(col_b) ranks
---------- ---------- ----------
----------
g1 a 475 1
g2 c 363 1
g2 b 154 2
g2 e 154 2
g2 d 66 3
g3 g 255 1
g3 f 154 2
可以看到名次都是在g列的組別發生變化時,就會重新開始新排列
;
sql分組求和
需求是 乙個月有多個發布額,現在要求按月統計發布額,例如 1月發布額 35900,2月發布額 2300 sql 語句如下 按月分組,求和 select dmonth,codename,sum iamount from 求出全部日期,發布額 select convert varchar 7 a.dre...
SQL技巧之分組求和
這是csdn問答裡面有人提出的一道問題,題目如下。如下 得出結果如下 求精簡的sql語句。sql查詢語句 with a as select rank over partition by 商店 order by 商店,sum 價錢 desc as rowid,商店,sum 價錢 as 價錢和,備註 f...
SQL技巧之分組求和
這是csdn問答裡面有人提出的一道問題,題目如下。如下 得出結果如下 求精簡的sql語句。sql查詢語句 with a as select rank over partition by 商店 order by 商店,sum 價錢 desc as rowid,商店,sum 價錢 as 價錢和,備註 f...