SQL Increment值取决于其他列中的更改

时间:2016-07-10 14:03:15

标签: sql sql-server

与此类似:T-SQL incrementing counter based on change in a column value

我有这张桌子:

ID  |  VALUE
5   |  A    
6   |  A    
6   |  A    
6   |  B    
6   |  A    
6   |  B    
6   |  B    
6   |  A    
6   |  C    

期望的结果是:

ID  |  VALUE    | GROUP
5   |  A        | 1
6   |  A        | 2
6   |  A        | 2
6   |  B        | 3
6   |  A        | 4
6   |  B        | 4
6   |  B        | 4
6   |  A        | 5
6   |  C        | 6

一个新列(GROUP),其值在前两列每次更改时递增,但在前两列值与上一行相同时不会递增。

到目前为止,使用RANK OVER()函数,我能做到的最好是:

ID  |  VALUE    | GROUP
5   |  A        | 1
6   |  A        | 2
6   |  A        | 2
6   |  B        | 3
6   |  A        | 2
6   |  B        | 3
6   |  B        | 3
6   |  A        | 1
6   |  C        | 4

1 个答案:

答案 0 :(得分:3)

我假设您有一个名为ordering的列,它指定记录的顺序。 SQL表代表无序集,因此没有"自然"订购行。

你可以通过行号的差异然后进行一些额外的操作来做你想要的事情:

select id, value, dense_rank() over (order by grp) as grouping
from (select t.*,
             min(ordering) over (partition by id, value, seqnum - seqnum_iv) as grp
      from (select t.*,
                   row_number() over (order by ordering) as seqnum,
                   row_number() over (partition by id, value order by ordering) as seqnum_iv
            from t
           ) t
     ) t;

最里面的子查询计算值序列。我鼓励你看看结果,看看发生了什么。每个岛屿的差异都是不变的。

第二个获得每个组ordering值的最小值。然后可以使用它将顺序值指定为最终结果。