Row_Number() 根据连续行进行分区

Posted

技术标签:

【中文标题】Row_Number() 根据连续行进行分区【英文标题】:Row_Number() partitioning according to consecutive rows 【发布时间】:2016-01-27 07:31:47 【问题描述】:

我正在处理 SQL Server 2008 的查询,该查询需要以考虑表中行的连续性质的方式进行分区,这意味着它没有“内存”并在连续性中断时重新开始行编号一个分区。

举例说明:

declare @test table 
(
CustomerId  varchar(10),
ItemId  varchar(10),
PlatformName varchar(10),
date    datetime
)

insert into @test values ('aaaa', 'x', 'mobile','2015-10-24 22:52:47')
insert into @test values ('aaaa', 'x', 'mobile','2015-10-23 22:56:47')
insert into @test values ('aaaa', 'k', 'mobile','2015-10-22 21:52:47')
insert into @test values ('aaaa', 'k', 'tablet','2015-10-20 22:12:47')
insert into @test values ('aaaa', 'x', 'mobile','2015-10-19 20:52:47')
insert into @test values ('aaaa', 'k', 'tablet','2015-10-18 12:52:47')
insert into @test values ('aaaa', 'k', 'tablet','2015-10-16 12:52:47')

SELECT
t.*,
ROW_NUMBER() OVER (PARTITION BY t.CustomerId,t.ItemId,t.PlatformName ORDER        BY t.Date DESC) as rowNo
FROM @test t
ORDER BY t.Date DESC 

以下查询返回:rowNo

1
2
1
1
3
2
3

而不是想要的:

1 
2 
1 
1 
1 
1 
2

在第 5 行和第 6 行的情况下,它应该重新开始计数,因为当您考虑连续性会将其与初始分区分开时,它是一个新分区。

我还需要按照行编号对行进行排序,如下所示:

1 
1 
2 
3 
4 
5 
6 
7 
7

【问题讨论】:

查看我对完全相同问题的回答***.com/questions/33298291/… 【参考方案1】:

您要做的是创建一个仅在分区更改时才更改的指标。您可以使用以下技巧来做到这一点。由于行号在给定分区内递增,如果您从每行内递增的数字中减去该行号,您将得到整个分区序列的相同数字。

这是任何分区开头的图表。

 row number     partition row number     row number-partition number    
     x                  1                     x-1
     x+1                2                     x-1
     ...
     x+n                n+1                   x-1

x 将在下一个分区发生变化,但分区编号将从 1 开始,并且您将在分区中的每一行获得相同的编号,直到下一个顺序分区。

然后您将此结果用作分区的一部分,您的问题就解决了。

下面是如何在 SQL 中编写代码:

WITH cte AS(SELECT *, ROW_NUMBER() OVER(Order By date DESC)
              - ROW_NUMBER() OVER(Partition By customerid, itemid, platformname
                                            Order By date DESC) rn FROM @test)
SELECT *, ROW_NUMBER() OVER(Partition By customerid, itemid, platformname, rn 
                                            Order By date DESC) rn2 
FROM cte
ORDER BY date DESC

【讨论】:

通过创建一个仅在分区更改时更改的数字来解释其工作原理会很有帮助。 @Hogan,好吧,除非您自己对陈述的不同部分进行解读,否则很难解释。这是标准的内陆解决方案。 我知道你是专门写的。好的,我给你做。 看...不难解释——不到 100 个字。 @Hogan,谢谢。我现在有一部智能手机......但我真的认为如果你没有在这里练习的话,这个解释很难理解。我仍然认为调试是理解它的方法。顺便说一句,你有一些错误。 will get the same number for every row in the partition 这不是真的...

以上是关于Row_Number() 根据连续行进行分区的主要内容,如果未能解决你的问题,请参考以下文章

oracle函数 ROW_NUMBER()

如何通过重复计数逻辑处理row_number分区中的空列?

在不使用 ROW_NUMBER() OVER 函数的情况下获取分区内行(排名)的序号

窗口函数 ROW_NUMBER

oracle中rownum和row_number()

SQL Server中row_number函数用法介绍