SQL Server Rank() Over Partition w/Back and Forth 值

Posted

技术标签:

【中文标题】SQL Server Rank() Over Partition w/Back and Forth 值【英文标题】:SQL Server Rank() Over Partition w/Back and Forth values 【发布时间】:2016-03-09 05:17:35 【问题描述】:

我正在对 TFS 数据库使用以下查询。有问题的工作项从活动状态变为其他状态并返回活动状态。我想使用 Rank() Over Partition 将两组“活动”状态视为单独的组,而不是将第二个活动组的编号继续与第一个活动组停止。

;with cte as
(
    SELECT 
        dense_rank() over(partition by ID, State order by ID,  Rev) as rn
        , ID
        , Rev
        , State
        , Reason
        , NamePart
        --, *
    FROM dbo.WorkItemsWere Hist
        Left JOIN Constants Cs WITH (nolock)
            ON Hist.[Changed by] = Cs.ConstID

    WHERE ID = 38728
)
SELECT * 
FROM cte
--WHERE rn = 1
ORDER BY ID, Rev

下面是我得到的结果集,其中添加了一个额外的“Desired rn”列,以显示我想要的结果:

Desired rn rn    ID          Rev         State                            
---------- ----- ----------- ----------- -----------------------------------
1          1     38728       1           Proposed                            
1          1     38728       2           Active                              
2          2     38728       3           Active                              
3          3     38728       4           Active                              
4          4     38728       5           Active                              
5          5     38728       6           Active                              
6          6     38728       7           Active                              
7          7     38728       8           Active                              
1          1     38728       9           Dev Complete                        
1          1     38728       10          Resolved; Queued for Build to Test  
2          2     38728       11          Resolved; Queued for Build to Test  
3          3     38728       12          Resolved; Queued for Build to Test 
1          8     38728       13          Active                             
2          9     38728       14          Active                             
1          2     38728       15          Dev Complete

这可以通过调整语法来完成吗?

【问题讨论】:

【参考方案1】:

使用ROW_NUMBERS的差异:

WITH CteGrp AS(
    SELECT *,
        Grp = ROW_NUMBER() OVER(PARTITION BY ID ORDER BY Rev)
                - ROW_NUMBER() OVER(PARTITION BY ID, State ORDER BY Rev)
    FROM tbl
),
Cte AS(
    SELECT *,
        rn = ROW_NUMBER() OVER(PARTITION BY ID, Grp ORDER BY Rev)
    FROM CteGrp
)
SELECT
    rn, ID, Rev, State 
FROM Cte
ORDER BY ID, Rev

DEMO


阅读 Jeff Moden 的文章了解有关此技术的更多信息:

Group Islands of Contiguous Dates (SQL Spackle) - SQLServerCentral

【讨论】:

非常优雅!工作完美!谢谢杰夫!感谢 Felix 指出技术/文章!

以上是关于SQL Server Rank() Over Partition w/Back and Forth 值的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server Rank() Over Partition w/Back and Forth 值

小5聊sql server 分页和分组-row_number()和over()rank()和over()的小区别

sql over表示啥意思

linq 如何实现sql rank over

mysql窗口函数rank() over、dense_rank() over、row_number() over 使用心得

sql 中 rank() over,dense_rank(),row_number() 的区别