詳解SQLServer中Partition By及row_number函數的使用

詳解SQLServer中Partition By及row_number函數的使用

partition? by關鍵字是分析性函數的一部分,它和聚合函數不同的地方在于它能返回一個分組中的多條記錄,而聚合函數一般只有一條反映統計值的記錄,partition? by用于給結果集分組,如果沒有指定那么它把整個結果集作為一個分組。

今天群里看到一個問題,在這里概述下:查詢出不同分類下的最新記錄。一看這不是很簡單的么,要分類那就用Group By;要最新記錄就用Order By唄。然后在自己的表中試著做出來:

相關學習推薦:mysql視頻教程

首先呢我把表中的數據按照提交時間倒序出來:

詳解SQLServer中Partition By及row_number函數的使用

“corp_name”就是分類的GUID(請原諒我命名的隨意性)。 OK, 這里按照最開始的想法加上Group By來看一下顯示效果:

詳解SQLServer中Partition By及row_number函數的使用

呃,嗯。這尼瑪和想象中的結果不一樣啊,看來寫代碼還是要理性分析問題,意念是無法控制結果滴!

既然要求是不同分類的數據,除了使用Group By之外,還有別的函數能用嗎?度娘了一下結果還真有,over(partition by )函數,那么它和平時用的Group By有什么區別呢? Group By除了對結果進行單純的分組之外呢,一般都和聚合函數一起使用,Partition By也具有分組功能,屬于Oracle的分析函數,在這里就不詳細的不啦不啦不啦了。

看代碼:

詳解SQLServer中Partition By及row_number函數的使用

over(partition by corp_name order by submit_time desc ) as t 。就是按照corp_name分類并按時間倒序出來,”t” 這里一列呢就是不同corp_name類出現的次數,需求是只查詢出不同分類的最新提交數據,那么我們只需要針對”t”再進行一次篩選即可:

詳解SQLServer中Partition By及row_number函數的使用

好啦,結果已經出來,不求各位看官喜歡,但求看在我頭像中的胸器望點個贊, 好人一生平安哦!!!

ps:SQL Server數據庫partition by 與ROW_NUMBER()函數使用詳解

關于SQL的partition by 字段的一些用法心得

先看例子:

if?object_id('TESTDB')?is?not?null?drop?table?TESTDB create?table?TESTDB(A?varchar(8),?B?varchar(8)) insert?into?TESTDB select?'A1',?'B1'?union?all select?'A1',?'B2'?union?all select?'A1',?'B3'?union?all select?'A2',?'B4'?union?all select?'A2',?'B5'?union?all select?'A2',?'B6'?union?all select?'A3',?'B7'?union?all select?'A3',?'B3'?union?all select?'A3',?'B4'

— 所有的信息

SELECT?*?FROM?TESTDB A??B ------- A1?B1 A1?B2 A1?B3 A2?B4 A2?B5 A2?B6 A3?B7 A3?B3 A3?B4

— 使用PARTITION BY 函數后

SELECT?*,ROW_NUMBER()?OVER(PARTITION?BY?A?ORDER?BY?A?DESC)?NUM?FROM?TESTDB A??B??NUM ------------- A1?B1?1 A1?B2?2 A1?B3?3 A2?B4?1 A2?B5?2 A2?B6?3 A3?B7?1 A3?B3?2 A3?B4?3

可以看到結果中多出一列NUM 這個NUM就是說明了相同行的個數,比如A1有3個,他就給每個A1標上是第幾個。

— 僅僅使用ROW_NUMBER() OVER的結果

SELECT?*,ROW_NUMBER()?OVER(ORDER?BY?A?DESC)NUM?FROM?TESTDB ?A??B???NUM ------------------------ A3?B7??1 A3?B3??2 A3?B4??3 A2?B4??4 A2?B5??5 A2?B6??6 A1?B1??7 A1?B2??8 A1?B3??9

可以看到它只是單純標出了行號。

— 深入一點應用

SELECT?A?=?CASE?WHEN?NUM?=?1?THEN?A?ELSE?''?END,B FROM?(SELECT?A,NUM?=?ROW_NUMBER()?OVER(PARTITION?BY?A?ORDER?BY?A?DESC)?FROM?TESTDB)?T A??B --------- A1?B1 ??B2 ??B3 A2?B4 ??B5 ??B6 A3?B7 ??B3 ??B4

接下來我們就通過幾個實例來一一介紹ROW_NUMBER()函數的使用。

實例如下:

1.使用row_number()函數進行編號,如

select?email,customerID,?ROW_NUMBER()?over(order?by?psd)?as?rows?from?QT_Customer

原理:先按psd進行排序,排序完后,給每條數據進行編號。

2.在訂單中按價格的升序進行排序,并給每條記錄進行排序代碼如下:

select?DID,customerID,totalPrice,ROW_NUMBER()?over(order?by?totalPrice)?as?rows?from?OP_Order

3.統計出每一個各戶的所有訂單并按每一個客戶下的訂單的金額 升序排序,同時給每一個客戶的訂單進行編號。這樣就知道每個客戶下幾單了

如圖:

?詳解SQLServer中Partition By及row_number函數的使用

代碼如下:

select?ROW_NUMBER()?over(partition?by?customerID?order?by?totalPrice)?as?rows,customerID,totalPrice,?DID?from?OP_Order

4.統計每一個客戶最近下的訂單是第幾次下的訂單。

?詳解SQLServer中Partition By及row_number函數的使用

代碼如下:

?with?tabs?as? (? select?ROW_NUMBER()?over(partition?by?customerID?order?by?totalPrice)?as?rows,customerID,totalPrice,?DID?from?OP_Order? ?)? select?MAX(rows)?as?'下單次數',customerID?from?tabs?group?by?customerID

5.統計每一個客戶所有的訂單中購買的金額最小,而且并統計改訂單中,客戶是第幾次購買的。

如圖:

詳解SQLServer中Partition By及row_number函數的使用

上圖:rows表示客戶是第幾次購買。

思路:利用臨時表來執行這一操作。

1.先按客戶進行分組,然后按客戶的下單的時間進行排序,并進行編號。

2.然后利用子查詢查找出每一個客戶購買時的最小價格。

3.根據查找出每一個客戶的最小價格來查找相應的記錄。

代碼如下:

with?tabs?as? ?(? select?ROW_NUMBER()?over(partition?by?customerID?order?by?insDT)?as?rows,customerID,totalPrice,?DID?from?OP_Order? )? ?select?*?from?tabs? where?totalPrice?in?? (? select?MIN(totalPrice)from?tabs?group?by?customerID? ?)

6.篩選出客戶第一次下的訂單。

詳解SQLServer中Partition By及row_number函數的使用

思路。利用rows=1來查詢客戶第一次下的訂單記錄。

代碼如下:

with?tabs?as? (? select?ROW_NUMBER()?over(partition?by?customerID?order?by?insDT)?as?rows,*?from?OP_Order? )? select?*?from?tabs?where?rows?=?1? select?*?from?OP_Order

7.rows_number()可用于分頁

思路:先把所有的產品篩選出來,然后對這些產品進行編號。然后在where子句中進行過濾。

8.注意:在使用over等開窗函數時,over里頭的分組及排序的執行晚于“where,group by,order by”的執行。

如下代碼:

select?? ROW_NUMBER()?over(partition?by?customerID?order?by?insDT)?as?rows,? customerID,totalPrice,?DID? from?OP_Order?where?insDT>'2011-07-22'

以上代碼是先執行where子句,執行完后,再給每一條記錄進行編號。

? 版權聲明
THE END
喜歡就支持一下吧
點贊8 分享