SQL Server:row_number 分区不重置计数器

Posted

技术标签:

【中文标题】SQL Server:row_number 分区不重置计数器【英文标题】:SQL Server : row_number partition does not reset counter 【发布时间】:2021-06-22 13:26:54 【问题描述】:

在下面的数据中,d1 更改为 d2,然后返回 d1,分区在 d 列上,因此分区正确地从第 2 行的 d1->d2 重置并且 rn = 1。我希望分区也可以重置d2->d1,即记录#3 也应该有 rn = 1。

如何解决这个问题?

SELECT
    t.*, 
    rn = ROW_NUMBER() OVER (PARTITION BY d ORDER BY id)
FROM   
    (VALUES (1, 'd1'), (2, 'd2'), (3, 'd1')) t (id, d)
ORDER BY
    id

【问题讨论】:

正确的;那是值 d12nd 行;第一个是id 的值为1 那么分区的顺序是什么。 d 列发生变化,因此它也必须是第三行的新分区 对数据进行分区...它完全按照它说的做,将数据分组。在这种情况下,d 的每个不同值对应 1 个组,d'd1''d2' 和 3 行只有两个不同的值,因此其中一行的值为 2 ;特定值的第二行。在这种情况下,当id 的值为3 时,这就是值'd1'第2 行。它的工作方式与预期完全一致,并且符合记录。 您可以将整体 row_number() - 1 除以 2 以获得分组的行号 【参考方案1】:

猜测您想在每次d 的值更改时以id 的值排序数据时开始行号,这与行号相同每个 d 的值。如果是这种情况,一种方法如下:

SELECT id,
       d,
       ROW_NUMBER() OVER (ORDER BY id ASC) -
       ROW_NUMBER() OVER (PARTITION BY d ORDER BY id ASC) AS RN
FROM dbo.YourTable;

【讨论】:

这会为第 2 行和第 3 行返回 1,我正在寻找每次值从上一行更改时重置的东西。【参考方案2】:

这可以完成工作,但看起来太笨重了。

select 
t.*, 
lagd=lag(d) over (order by id),
change= (case when d= (lag(d) over (order by id)) then 0 else 1 end)
FROM   (VALUES          (1,'d1' ),
                        (2,'d2' ),
                        (3,'d1' ),
                        (4,'d2' ),
                        (5,'d2' )
                        ) t (id, d)
order by id

【讨论】:

以上是关于SQL Server:row_number 分区不重置计数器的主要内容,如果未能解决你的问题,请参考以下文章

ROW_NUMBER SQL Server 2005的LIMIT功能实现(ROW_NUMBER()排序函数)

在禁用分区功能的 SQL 中使用分区上的 Row_number

根据sql server 2012中后续行索引之间的差异创建分区

SQL 最近在分区上使用 row_number()

sql2000不支持Row_Number() over吗

如何在 SQL Server 2008 中进行分页