1. 程式人生 > >(轉)常用統計分析函式

(轉)常用統計分析函式

(1)sum函式,統計總合
按照月份,統計每個地區的總收入
Sql程式碼

select earnmonth, area, sum(personincome)
from earnings
group by earnmonth,area;
檢視結果如下:

(2)rollup函式
按照月份,地區統計收入,主要用於做小計合計
select earnmonth, area, sum(personincome)
from earnings
–group by rollup(area,earnmonth); ----該行程式碼計算出的結果是以城市group by的
group by rollup(earnmonth,area); ----該行程式碼計算出的結果是以月份group by的
檢視結果如下:

group by 後面接 rollup 是在純粹的 group by 分組上再加上對earnmonth的彙總統計。

(3)cube函式
按照月份,地區進行收入總彙總
Sql程式碼

select earnmonth, area, sum(personincome)
from earnings
–group by cube(earnmonth,area) ----括號中內容順序對結果集沒有影響
group by cube(area,earnmonth)
order by earnmonth,area nulls last; ---- nulls last 是把空值放在最後
結果如下:

group by 後面接 cube 是對earnmonth彙總統計基礎上對area再統計。

rollup和cube區別:

如果是ROLLUP(A, B, C)的話,GROUP BY順序
(A、B、C)
(A、B)
(A)
最後對全表進行GROUP BY操作。

如果是GROUP BY CUBE(A, B, C),GROUP BY順序
(A、B、C)
(A、B)
(A、C)
(A),
(B、C)
(B)
©,
最後對全表進行GROUP BY操作。

(4)grouping函式
在以上例子中,是用rollup和cube函式都會對結果集產生null,這時候可用grouping函式來確認
該記錄是由哪個欄位得出來的
grouping函式用法,帶一個引數,引數為欄位名,如果當前行是由rollup或者cube彙總得來的,有結果就返回1,反之返回0
SELECT
(CASE WHEN grouping(EARNMONTH) =1 THEN ‘所有月份’
ELSE EARNMONTH END) “月份”,
(CASE WHEN grouping(AREA) =1 THEN ‘全部地區’
ELSE AREA END) “地區維度”,
sum(PERSONINCOME)“工資”
FROM EARNINGS
GROUP BY CUBE (EARNMONTH,AREA)
ORDER BY EARNMONTH,AREA NULLS LAST ;

(5)rank() over開窗函式:則是重複值所在行的序列值相同,但其後的序列值從重複行數開始遞增
按照月份、地區,求打工收入排序
select
earnmonth 月份,
area 地區,
sname 打工者,
personincome 收入,
rank() over (partition by earnmonth,area order by personincome desc) 排名
from earnings;

(6)dense_rank() over開窗函式:在做排序時如果遇到列有重複值,則重複值所在行的序列值相同,而其後的序列值依舊遞增
按照月份、地區,求打工收入排序2
select
earnmonth 月份,
area 地區,sname 打工者,
personincome 收入,
dense_rank() over (partition by earnmonth,area order by personincome desc) 排名
from earnings;

(7)row_number() over:不管是否有重複行,(分組內)序列值始終遞增
按照月份、地區,求打工收入排序3
select
earnmonth 月份,
area 地區,
sname 打工者,
personincome 收入,
row_number() over (partition by earnmonth,area order by personincome desc) 排名
from earnings;

(8)sum累計求和
根據月份求出各個打工者收入總和,按照收入由少到多排序
select
earnmonth 月份,
area 地區,
sname 打工者,
sum(personincome) over (partition by earnmonth,area order by personincome) 總收入
from earnings;

(9)max,min,avg和sum函式綜合運用
按照月份和地區求打工收入最高值,最低值,平均值和總額
select
distinct earnmonth 月份,
area 地區,
max(personincome) over(partition by earnmonth,area) 最高值,
min(personincome) over(partition by earnmonth,area) 最低值,
avg(personincome) over(partition by earnmonth,area) 平均值,
sum(personincome) over(partition by earnmonth,area) 總額
from earnings;

(10)lag和lead函式
求出每個打工者上個月和下個月有沒有賺錢(personincome大於零即為賺錢)
select earnmonth 本月,
sname 打工者,
lag(decode(nvl(personincome,0),0,‘沒賺’,‘賺了’),1,0) over(partition by sname order by earnmonth) 上月,
lead(decode(nvl(personincome,0),0,‘沒賺’,‘賺了’),1,0) over(partition by sname order by earnmonth) 下月
from earnings;

說明:Lag和Lead函式可以在一次查詢中取出某個欄位的前N行和後N行的資料(可以是其他欄位的資料,比如根據欄位甲查詢上一行或下兩行的欄位乙),原來沒有分析函式的時候採用子查詢方法,但是比較麻煩,慚愧,我用子查詢有的還查不出來呢。

語法如下:
lag(value_expression [,offset] [,default]) over ([query_partition_clase] order_by_clause);
lead(value_expression [,offset] [,default]) over ([query_partition_clase] order_by_clause);
其中:
value_expression:可以是一個欄位或一個內建函式。
offset是正整數,預設為1,指往前或往後幾點記錄.因組內第一個條記錄沒有之前的行,最後一行沒有之後的行,
default就是用於處理這樣的資訊,預設為空。

再講講所謂的開窗函式,依本人遇見,開窗函式就是 over([query_partition_clase] order_by_clause)。比如說,我採用sum求和,rank排序等等,但是我根據什麼來呢?over提供一個視窗,可以根據什麼什麼分組,就用partition by,然後在組內根據什麼什麼進行內部排序,就用 order by。

資料庫建立語句及資料插入語句
本文講述Oracle分析函式用法,首先建庫:
Sql程式碼

create table earnings – 打工賺錢表
(
earnmonth varchar2(6), – 打工月份
area varchar2(20), – 打工地區
sno varchar2(10), – 打工者編號
sname varchar2(20), – 打工者姓名
times int, – 本月打工次數
singleincome number(10,2), – 每次賺多少錢
personincome number(10,2) – 當月總收入
)
然後插入實驗資料:
Sql程式碼

insert into earnings values(‘200912’,‘北平’,‘511601’,‘大魁’,11,30,1130);
insert into earnings values(‘200912’,‘北平’,‘511602’,‘大凱’,8,25,8
25);
insert into earnings values(‘200912’,‘北平’,‘511603’,‘小東’,30,6.25,306.25);
insert into earnings values(‘200912’,‘北平’,‘511604’,‘大亮’,16,8.25,16
8.25);
insert into earnings values(‘200912’,‘北平’,‘511605’,‘賤敬’,30,11,30*11);

insert into earnings values(‘200912’,‘金陵’,‘511301’,‘小玉’,15,12.25,1512.25);
insert into earnings values(‘200912’,‘金陵’,‘511302’,‘小凡’,27,16.67,27
16.67);
insert into earnings values(‘200912’,‘金陵’,‘511303’,‘小妮’,7,33.33,733.33);
insert into earnings values(‘200912’,‘金陵’,‘511304’,‘小俐’,0,18,0);
insert into earnings values(‘200912’,‘金陵’,‘511305’,‘雪兒’,11,9.88,11
9.88);

insert into earnings values(‘201001’,‘北平’,‘511601’,‘大魁’,0,30,0);
insert into earnings values(‘201001’,‘北平’,‘511602’,‘大凱’,14,25,1425);
insert into earnings values(‘201001’,‘北平’,‘511603’,‘小東’,19,6.25,19
6.25);
insert into earnings values(‘201001’,‘北平’,‘511604’,‘大亮’,7,8.25,78.25);
insert into earnings values(‘201001’,‘北平’,‘511605’,‘賤敬’,21,11,21
11);

insert into earnings values(‘201001’,‘金陵’,‘511301’,‘小玉’,6,12.25,612.25);
insert into earnings values(‘201001’,‘金陵’,‘511302’,‘小凡’,17,16.67,17
16.67);
insert into earnings values(‘201001’,‘金陵’,‘511303’,‘小妮’,27,33.33,2733.33);
insert into earnings values(‘201001’,‘金陵’,‘511304’,‘小俐’,16,18,16
18);
insert into earnings values(‘201001’,‘金陵’,‘511305’,‘雪兒’,11,9.88,11*9.88);
然後看看剛剛建好的庫:
Sql程式碼

select * from earnings;