【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 KEY  IDENTITY(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])
12      VALUES
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 (
5     select 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 (
5     select 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 (
5     select Id,UserId,TotalPrice,orderTime,ROW_NUMBER() over (partition by UserId order by orderTime) as rowIndex from OrderInfo
6     where OrderTime>'2011-1-1'
7 )
8 select * from baseDate where rowIndex=1

5、只保留每個客戶的最近的一次訂單,其余的訂單刪掉。(常用於刪除重復數據)

1 with
2 baseDate
3 as
4 (
5     select 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 (
 5     select Id,UserId,TotalPrice,orderTime,ROW_NUMBER() over (partition by UserId order by orderTime) as rowIndex from OrderInfo
 6 ),
 7 basePrice
 8 as
 9 (
10     select 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 (
14     select Id from basePrice where rowIndex=1
15 )

 

#圖中的rowIndex字段就是該訂單是第幾次購買;

 


免責聲明!

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



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