日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[转]oracle分析函数Rank, Dense_rank, row_number

發布時間:2023/11/30 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [转]oracle分析函数Rank, Dense_rank, row_number 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

oracle分析函數Rank, Dense_rank, row_number

分析函數2(Rank, Dense_rank, row_number)

?

目錄
===============================================
1.使用rownum為記錄排名
2.使用分析函數來為記錄排名
3.使用分析函數為記錄進行分組排名

一、使用rownum為記錄排名:

在前面一篇《Oracle開發專題之:分析函數》,我們認識了分析函數的基本應用,現在我們再來考慮下面幾個問題:

①對所有客戶按訂單總額進行排名
②按區域和客戶訂單總額進行排名
③找出訂單總額排名前13位的客戶
④找出訂單總額最高、最低的客戶
⑤找出訂單總額排名前25%的客戶

按照前面第一篇文章的思路,我們只能做到對各個分組的數據進行統計,如果需要排名的話那么只需要簡單地加上rownum不就行了嗎?事實情況是否如此想象般簡單,我們來實踐一下。

【1】測試環境:

SQL>?desc?user_order;
?Name??????????????????????????????????????Null?????Type
?-----------------------------------------?--------?----------------------------
?REGION_ID??????????????????????????????????????????NUMBER(2)
?CUSTOMER_ID??????????????????????????????????NUMBER(2)
?CUSTOMER_SALES??????????????????????????NUMBER


【2】測試數據:

SQL>?select?*?from?user_order?order?by?customer_sales;

?REGION_ID?CUSTOMER_ID?CUSTOMER_SALES
----------?-----------?--------------
?????????5???????????1????????????? 151162
????????10??????????29????????? ?? 903383
?????????6???????????7????????????? 971585
????????10??????????28??????????? 986964
?????????9??????????21???????????1020541
?????????9??????????22?????????? 1036146
?????????8??????????16?????????? 1068467
?????????6???????????8??????????? 1141638
?????????5???????????3??????????? 1161286
?????????5???????????5??????????? 1169926
?????????8??????????19?????????? 1174421
?????????7??????????12?????????? 1182275
?????????7??????????11?????????? 1190421
?????????6??????????10?????????? 1196748
?????????6???????????9??????????? 1208959
????????10??????????30??????????1216858
?????????5???????????? 2??????????????? 1224992
???????????9???????????? 24????????????? 1224992
???????????9???????????? 23????????????? 1224992
?????????? 8
??????????18?????????? 1253840
?????????7??????????15?????????? 1255591
?????????7??????????13?????????? 1310434
????????10??????????27????????? 1322747
?????????8??????????20?????????? 1413722
?????????6???????????6??????????? 1788836
????????10??????????26????????? 1808949
?????????5???????????4??????????? 1878275
?????????7??????????14?????????? 1929774
?????????8??????????17?????????? 1944281
?????????9??????????25?????????? 2232703

30?rows?selected.


注意這里有3條記錄的訂單總額是一樣的。假如我們現在需要篩選排名前12位的客戶,如果使用rownum會有什么樣的后果呢?

SQL>?select?rownum,?t.*
??2????from?(select?*?
??3????????????from?user_order
??4???????????order?by?customer_sales?desc)?t
??5???where?rownum?<=?12
??6???order?by?customer_sales?desc;

????ROWNUM??REGION_ID?CUSTOMER_ID?CUSTOMER_SALES
----------?----------?-----------?--------------
?????????1??????????9???????????????? 25????????2232703
?????????2??????????8???????????????? 17????????1944281
?????????3??????????7?????????????????14????????1929774
?????????4??????????5???????????????????4????????1878275
?????????5?????????10????????????????26????????1808949
?????????6??????????6?????????????????? 6????????1788836
?????????7??????????8???????????????? 20????????1413722
?????????8?????????10??????????????? 27????????1322747
?????????9??????????7??????????????? 13????????1310434
????????10??????????7?????????????? 15????????1255591
????????11??????????8?????????????? 18????????1253840
????????? 12???????????? 5???????????????????? 2????????? 1224992

12?rows?selected.


很明顯假如只是簡單地按rownum進行排序的話,我們漏掉了另外兩條記錄(參考上面的結果)。

二、使用分析函數來為記錄排名:

針對上面的情況,Oracle從8i開始就提供了3個分析函數:rand,dense_rank,row_number來解決諸如此類的問題,下面我們來看看這3個分析函數的作用以及彼此之間的區別:

Rank,Dense_rank,Row_number函數為每條記錄產生一個從1開始至N的自然數,N的值可能小于等于記錄的總數。這3個函數的唯一區別在于當碰到相同數據時的排名策略。

ROW_NUMBER

Row_number函數返回一個唯一的值,當碰到相同數據時,排名按照記錄集中記錄的順序依次遞增。?

DENSE_RANK
Dense_rank函數返回一個唯一的值,除非當碰到相同數據時,此時所有相同數據的排名都是一樣的。?

RANK
Rank函數返回一個唯一的值,除非遇到相同的數據時,此時所有相同數據的排名是一樣的,同時會在最后一條相同記錄和下一條不同記錄的排名之間空出排名。

這樣的介紹有點難懂,我們還是通過實例來說明吧,下面的例子演示了3個不同函數在遇到相同數據時不同排名策略:

SQL>?select?region_id,?customer_id,?sum(customer_sales)?total,
??2?????????rank()?over(order?by?sum(customer_sales)?desc)?rank,
??3?????????dense_rank()?over(order?by?sum(customer_sales)?desc)?dense_rank,
??4?????????row_number()?over(order?by?sum(customer_sales)?desc)?row_number
??5????from?user_order
??6???group?by?region_id,?customer_id;

?REGION_ID?CUSTOMER_ID??????TOTAL???????RANK?DENSE_RANK?ROW_NUMBER
----------?-----------?----------?----------?----------?----------
? ? ????????
?????????8??????????18????????????????1253840?????????11?????????11?????????11
?????????5???????????2?????????????????1224992?????????12?????????12?????????12
?????????9??????????23????????????????1224992?????????12?????????12?????????13
?????????9??????????24????????????????1224992?????????12?????????12?????????14
????????10??????????30???????????????1216858?????????15?????????? 13??????????? 15
? ?

30?rows?selected.


請注意上面的綠色高亮部分,這里生動的演示了3種不同的排名策略:

①對于第一條相同的記錄,3種函數的排名都是一樣的:12

②當出現第二條相同的記錄時,Rank和Dense_rank依然給出同樣的排名12;而row_number則順延遞增為13,依次類推至第三條相同的記錄

③當排名進行到下一條不同的記錄時,可以看到Rank函數在12和15之間空出了13,14的排名,因為這2個排名實際上已經被第二、三條相同的記錄占了。而Dense_rank則順序遞增。row_number函數也是順序遞增

比較上面3種不同的策略,我們在選擇的時候就要根據客戶的需求來定奪了:

①假如客戶就只需要指定數目的記錄,那么采用row_number是最簡單的,但有漏掉的記錄的危險

②假如客戶需要所有達到排名水平的記錄,那么采用rankdense_rank是不錯的選擇。至于選擇哪一種則看客戶的需要,選擇dense_rank或得到最大的記錄

三、使用分析函數為記錄進行分組排名:

上面的排名是按訂單總額來進行排列的,現在跟進一步:假如是為各個地區的訂單總額進行排名呢?這意味著又多了一次分組操作:對記錄按地區分組然后進行排名。幸虧Oracle也提供了這樣的支持,我們所要做的僅僅是在over函數中order by的前面增加一個分組子句:partition by region_id。

SQL>?select?region_id,?customer_id,?
???????????????sum(customer_sales)?total,
??2?????????rank()?over(partition?by?region_id
????????????????????????order?by?sum(customer_sales)?desc)?rank,
??3?????????dense_rank()?over(partition?by?region_id
????????????????????????order?by?sum(customer_sales)?desc)?dense_rank,
??4?????????row_number()?over(partition?by?region_id
????????????????????????order?by?sum(customer_sales)?desc)?row_number

??5????from?user_order
??6???group?by?region_id,?customer_id;

?REGION_ID?CUSTOMER_ID??????TOTAL???????RANK?DENSE_RANK?ROW_NUMBER
----------?-----------?----------?----------?----------?----------
?????????5???????????4????????????????1878275??????????1??????????1??????????1
?????????5???????????2??????????????? 1224992??????????2??????????2??????????2
?????????5???????????5??????????????? 1169926??????????3??????????3??????????3
?????????6???????????6??????????????? 1788836??????????1??????????1??????????1
?????????6???????????9??????????????? 1208959??????????2??????????2??????????2
?????????6??????????10????????????? ?1196748??????????3??????????3??????????3???????
?

30?rows?selected.


現在我們看到的排名將是基于各個地區的,而非所有區域的了!Partition by 子句在排列函數中的作用是將一個結果集劃分成幾個部分,這樣排列函數就能夠應用于這各個子集。

前面我們提到的5個問題已經解決了2個了(第1,2),剩下的3個問題(Top/Bottom N,First/Last, NTile)會在下一篇講解。

?原文地址:http://www.cnblogs.com/wuyisky/archive/2010/02/24/oracle_rank.html

轉載于:https://www.cnblogs.com/autumnlj/p/5815297.html

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的[转]oracle分析函数Rank, Dense_rank, row_number的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。