Oracle分析函數

來源:互聯網
上載者:User

標籤:

本文講述Oracle分析函數用法,首先建庫:

Sql代碼  
  1. create table earnings -- 打工賺錢表  
  2. (  
  3.   earnmonth varchar2(6), -- 打工月份  
  4.   area varchar2(20), -- 打工地區  
  5.   sno varchar2(10), -- 打工者編號  
  6.   sname varchar2(20), -- 打工者姓名  
  7.   times int, -- 本月打工次數  
  8.   singleincome number(10,2), -- 每次賺多少錢  
  9.   personincome number(10,2) -- 當月總收入  
  10. )  

然後插入實驗資料:

Sql代碼  
  1. insert into earnings values(‘200912‘,‘北平‘,‘511601‘,‘大魁‘,11,30,11*30);  
  2. insert into earnings values(‘200912‘,‘北平‘,‘511602‘,‘大凱‘,8,25,8*25);  
  3. insert into earnings values(‘200912‘,‘北平‘,‘511603‘,‘小東‘,30,6.25,30*6.25);  
  4. insert into earnings values(‘200912‘,‘北平‘,‘511604‘,‘大亮‘,16,8.25,16*8.25);  
  5. insert into earnings values(‘200912‘,‘北平‘,‘511605‘,‘賤敬‘,30,11,30*11);  
  6.   
  7. insert into earnings values(‘200912‘,‘金陵‘,‘511301‘,‘小玉‘,15,12.25,15*12.25);  
  8. insert into earnings values(‘200912‘,‘金陵‘,‘511302‘,‘小凡‘,27,16.67,27*16.67);  
  9. insert into earnings values(‘200912‘,‘金陵‘,‘511303‘,‘小妮‘,7,33.33,7*33.33);  
  10. insert into earnings values(‘200912‘,‘金陵‘,‘511304‘,‘小俐‘,0,18,0);  
  11. insert into earnings values(‘200912‘,‘金陵‘,‘511305‘,‘雪兒‘,11,9.88,11*9.88);  
  12.   
  13. insert into earnings values(‘201001‘,‘北平‘,‘511601‘,‘大魁‘,0,30,0);  
  14. insert into earnings values(‘201001‘,‘北平‘,‘511602‘,‘大凱‘,14,25,14*25);  
  15. insert into earnings values(‘201001‘,‘北平‘,‘511603‘,‘小東‘,19,6.25,19*6.25);  
  16. insert into earnings values(‘201001‘,‘北平‘,‘511604‘,‘大亮‘,7,8.25,7*8.25);  
  17. insert into earnings values(‘201001‘,‘北平‘,‘511605‘,‘賤敬‘,21,11,21*11);  
  18.   
  19. insert into earnings values(‘201001‘,‘金陵‘,‘511301‘,‘小玉‘,6,12.25,6*12.25);  
  20. insert into earnings values(‘201001‘,‘金陵‘,‘511302‘,‘小凡‘,17,16.67,17*16.67);  
  21. insert into earnings values(‘201001‘,‘金陵‘,‘511303‘,‘小妮‘,27,33.33,27*33.33);  
  22. insert into earnings values(‘201001‘,‘金陵‘,‘511304‘,‘小俐‘,16,18,16*18);  
  23. insert into earnings values(‘201001‘,‘金陵‘,‘511305‘,‘雪兒‘,11,9.88,11*9.88);  

然後看看剛剛建好的庫:

Sql代碼  
  1. select * from earnings;  

 

 

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

Sql代碼  
  1. select earnmonth, area, sum(personincome)  
  2. from earnings  
  3. group by earnmonth,area;  

 查看結果如下:

 

(2)rollup函數
按照月份,地區統計收入

Sql代碼  
  1. select earnmonth, area, sum(personincome)  
  2. from earnings  
  3. group by rollup(earnmonth,area);  

 查看結果如下:

 

(3)cube函數
按照月份,地區進行收入總匯總

Sql代碼  
  1. select earnmonth, area, sum(personincome)  
  2. from earnings  
  3. group by cube(earnmonth,area)  
  4. order by earnmonth,area nulls last;  

 結果如下:

 

小結:sum是統計求和的函數。
group by 是分組函數,按照earnmonth和area先後次序分組。
以上三例都是先按照earnmonth分組,在earnmonth內部再按area分組,並在area組內統計personincome總合。
group by 後面什麼也不接就是直接分組。
group by 後面接 rollup 是在純粹的 group by 分組上再加上對earnmonth的匯總統計。
group by 後面接 cube 是對earnmonth匯總統計基礎上對area再統計。
另外那個 nulls last 是把空值放在最後。 

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)
(C),
最後對全表進行GROUP BY操作。

 

(4)grouping函數
在以上例子中,是用rollup和cube函數都會對結果集產生null,這時候可用grouping函數來確認
該記錄是由哪個欄位得出來的
grouping函數用法,帶一個參數,參數為欄位名,結果是根據該欄位得出來的就返回1,反之返回0

Sql代碼  
  1. select decode(grouping(earnmonth),1,‘所有月份‘,earnmonth) 月份,  
  2.        decode(grouping(area),1,‘全部地區‘,area) 地區, sum(personincome) 總金額  
  3. from earnings  
  4. group by cube(earnmonth,area)  
  5. order by earnmonth,area nulls last;  

 查看結果如下:

 

(5)rank() over開窗函數
按照月份、地區,求打工收入排序

Sql代碼  
  1. select earnmonth 月份,area 地區,sname 打工者, personincome 收入,   
  2.        rank() over (partition by earnmonth,area order by personincome desc) 排名  
  3. from earnings;  

 查看結果:

 

(6)dense_rank() over開窗函數
按照月份、地區,求打工收入排序2

Sql代碼  
  1. select earnmonth 月份,area 地區,sname 打工者, personincome 收入,   
  2.        dense_rank() over (partition by earnmonth,area order by personincome desc) 排名  
  3. from earnings;  

 結果如下:

 

(7)row_number() over開窗函數
按照月份、地區,求打工收入排序3

Sql代碼  
  1. select earnmonth 月份,area 地區,sname 打工者, personincome 收入,   
  2.        row_number() over (partition by earnmonth,area order by personincome desc) 排名  
  3. from earnings;  

 結果如下:

 

通過(5)(6)(7)發現rank,dense_rank,row_number的區別:
結果集中如果出現兩個相同的資料,那麼rank會進行跳躍式的排名,
比如兩個第二,那麼沒有第三接下來就是第四;
但是dense_rank不會跳躍式的排名,兩個第二接下來還是第三;
row_number最牛,即使兩個資料相同,排名也不一樣。

 

(8)sum累計求和
根據月份求出各個打工者收入總和,按照收入由少到多排序

Sql代碼  
  1. select earnmonth 月份,area 地區,sname 打工者,   
  2.        sum(personincome) over (partition by earnmonth,area order by personincome) 總收入  
  3. from earnings;  

 查看結果如下:

 

(9)max,min,avg和sum函數綜合運用
按照月份和地區求打工收入最高值,最低值,平均值和總額

Sql代碼  
  1. select distinct earnmonth 月份, area 地區,  
  2.        max(personincome) over(partition by earnmonth,area) 最高值,  
  3.        min(personincome) over(partition by earnmonth,area) 最低值,  
  4.        avg(personincome) over(partition by earnmonth,area) 平均值,  
  5.        sum(personincome) over(partition by earnmonth,area) 總額  
  6. from earnings;  

 結果如下:

 

(10)lag和lead函數
求出每個打工者上個月和下個月有沒有賺錢(personincome大於零即為賺錢)

Sql代碼  
  1. select earnmonth 本月,sname 打工者,  
  2.        lag(decode(nvl(personincome,0),0,‘沒賺‘,‘賺了‘),1,0) over(partition by sname order by earnmonth) 上月,  
  3.        lead(decode(nvl(personincome,0),0,‘沒賺‘,‘賺了‘),1,0) over(partition by sname order by earnmonth) 下月  
  4. 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分析函數

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.