【SQL】ROW_NUMBER() OVER(partition by 分組列 order by 排序列)用法詳解+經典例項
#用法說明
select row_number() over(partition by A order by B ) as rowIndex from table
A :為分組欄位
B:為分組後的排序欄位。
table 表的結構 多為: 多人 多條的相關資料。(比如:訂單資訊)
此條sql語句,多用於對資料進行 分組排序 ,並對每個組中的資料分別進行 編號 ,編號從1開始遞增,每個組內的編號不會重複;
#經典例項
0、填充資料
1 create table [OrderInfo]( 2[Id] [int] PRIMARY KEYIDENTITY(1,1) NOT NULL, 3[UserId] [nvarchar](50) NOT NULL, 4[TotalPrice] [float] NOT NULL, 5[OrderTime] [datetime] NOT NULL, 6 ); 7 8 INSERT INTO [dbo].[OrderInfo] 9([UserId] 10,[TotalPrice] 11,[OrderTime]) 12VALUES 13(N'1', 111, CAST(N'2011-01-01' AS DateTime)), 14(N'1', 112, CAST(N'2011-01-02' AS DateTime)), 15(N'3', 311, CAST(N'2013-01-01' AS DateTime)), 16(N'3', 312, CAST(N'2013-01-02' AS DateTime)), 17(N'2', 211, CAST(N'2012-01-01' AS DateTime)), 18(N'2', 212, CAST(N'2012-01-02' AS DateTime)), 19(N'1', 113, CAST(N'2011-01-03' AS DateTime)), 20(N'2', 213, CAST(N'2012-01-03' AS DateTime)), 21(N'3', 313, CAST(N'2013-01-03' AS DateTime)) 22 GO
1、使用row_number()函式對訂單進行編號,按照訂單時間倒序。(此需求多用於分頁)
1 select Id,UserId,TotalPrice,OrderTime,ROW_NUMBER() over (order by OrderTime desc) as rowIndex from OrderInfo
# 分頁場景:每頁3條資料,取第2頁
1 with 2 baseDate 3 as 4 ( 5select Id,UserId,TotalPrice,OrderTime,ROW_NUMBER() over (order by OrderTime desc) as rowIndex from OrderInfo 6 ) 7 select * from baseDate where rowIndex>3 and rowIndex<7
2、所有訂單按照客戶進行分組,並按照客戶下的訂單的金額倒序排列。
1 select Id,UserId,orderTime,ROW_NUMBER() over(partition by UserId order by TotalPrice desc) as rowIndex from OrderInfo
3、篩選出客戶第一次下的訂單。
思路:利用rowIndex來判斷訂單是客戶第幾次下單;
1 with 2 baseDate 3 as 4 ( 5select Id,UserId,TotalPrice,orderTime,ROW_NUMBER() over (partition by UserId order by orderTime) as rowIndex from OrderInfo 6 ) 7 select * from baseDate where rowIndex=1
4、篩選出客戶在‘2011年1月1日之後的第一次下的訂單。
思路:在分組排序之前進行實踐篩選;
注意 : 在使用over等開窗函式時,over裡頭的分組及排序的執行晚於“where,group by,order by”的執行。
1 with 2 baseDate 3 as 4 ( 5select Id,UserId,TotalPrice,orderTime,ROW_NUMBER() over (partition by UserId order by orderTime) as rowIndex from OrderInfo 6where OrderTime>'2011-1-1' 7 ) 8 select * from baseDate where rowIndex=1
5、只保留每個客戶的最近的一次訂單,其餘的訂單刪掉。(常用於刪除重複資料)
1 with 2 baseDate 3 as 4 ( 5select Id,UserId,TotalPrice,OrderTime,ROW_NUMBER()over (partition by UserId order by OrderTime desc) as rowIndex from OrderInfo 6 ) 7 delete from baseDate where rowIndex <> 1
6、統計 每一個客戶 所有的訂單中 金額最大 ,並統計該訂單是客戶 第幾次 購買;
思路:
1)先按照客戶進行分組,然後按照客戶下單的時間進行正序排列,並編號(rowIndex),生成臨時表baseDate;
2)再按照客戶進行分組,然後按照客戶下單的金額進行倒序排列,並編號(rowIndex),生成臨時表basePrice;
3)最後取basePrice中編號為1的資料,然後根據id到baseDate中去查,即可;
1 with 2 baseDate 3 as 4 ( 5select Id,UserId,TotalPrice,orderTime,ROW_NUMBER() over (partition by UserId order by orderTime) as rowIndex from OrderInfo 6 ), 7 basePrice 8 as 9 ( 10select Id,UserId,orderTime,ROW_NUMBER() over(partition by UserId order by TotalPrice desc) as rowIndex from OrderInfo 11 ) 12 select * from baseDate 13 where Id in ( 14select Id from basePrice where rowIndex=1 15 )
# 圖中的 rowIndex 欄位就是該訂單是第幾次購買;