oracle中partition by分組排序函數用法


項目開發中,我們有時會碰到需要分組排序來解決問題的情況,如:1、要求取出按field1分組后,並在每組中按照field2排序;2、亦或更加要求取出1中已經分組排序好的前多少行的數據

這里通過一張表的示例和SQL語句闡述下oracle數據庫中用於分組排序函數的用法。

a、row_number() over()

row_number()over(partition by col1 order by col2)表示根據col1分組,在分組內部根據col2排序,而此函數計算的值就表示每組內部排序后的順序編號(組內連續的唯一的)。
與rownum的區別在於:使用rownum進行排序的時候是先對結果集加入偽劣rownum然后再進行排序,而此函數在包含排序從句后是先排序再計算行號碼。row_number()和rownum差不多,功能更強一點(可以在各個分組內從1開始排序)。
b、rank() over()

rank()是跳躍排序,有兩個第二名時接下來就是第四名(同樣是在各個分組內)

c、dense_rank() over()

dense_rank()也是連續排序,有兩個第二名時仍然跟着第三名。相比之下row_number是沒有重復值的。

 

示例:

如有表Test,數據如下

 

Java代碼   收藏代碼
  1. CREATEDATE      ACCNO   MONEY  
  2. 2014/6/5           111      200   
  3. 2014/6/4           111      600   
  4. 2014/6/5           111      400   
  5. 2014/6/6           111      300   
  6. 2014/6/6           222      200   
  7. 2014/6/5           222      800   
  8. 2014/6/6           222      500   
  9. 2014/6/7           222      100   
  10. 2014/6/6           333      800   
  11. 2014/6/7           333      500   
  12. 2014/6/8           333      200   
  13. 2014/6/9           333      0  

  

比如要根據ACCNO分組,並且每組按照CREATEDATE排序,是組內排序,並不是所有的數據統一排序,

用下列語句實現:

 

 

Sql代碼   收藏代碼
  1. select t.*,row_number() over(partition by accno order by createDate) row_number from Test t  

 

查詢結果如下:

 

 

 

大家可以注意到ACCNO為111的記錄有兩個相同的CREATEDATE,用row_number函數,他們的組內計數是連續唯一的,但是如果用rank或者dense_rank函數,效果就不一樣,如下:

rank的sql:

Sql代碼   收藏代碼
  1. select t.*,rank() over(partition by accno order by createDate) rank from Test t  

 

查詢結果:



 

可以發現相同CREATEDATE的兩條記錄是兩個第2時接下來就是第4.

 

dense_rank的sql:

Sql代碼   收藏代碼
  1. select t.*,dense_rank() over(partition by accno order by createDate) dense_rank from Test t  

 

查詢結果:



 

可以發現相同CREATEDATE的兩個字段是兩個第2時接下來就是第3.

 

項目中特殊的業務需求可能會要求用以上三個不同的函數,具體情況具體對待。

 

 

再比如有時會要求分組排序后分別取出各組內前多少的數據記錄,sql如下:

Sql代碼   收藏代碼
  1. select createDate,accno,money,row_number from  (select t.*,row_number() over(partition by accno order by createDate) row_number from Test t) t1 where row_number<4  

  

 

查詢結果如下:



 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM