【问题标题】:SQL Increment value depending on changes in other columnsSQL 增量值取决于其他列的变化
【发布时间】:2016-11-12 13:28:15
【问题描述】:

与此类似: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

【问题讨论】:

  • SQL Server 表没有内在顺序。请在您的问题中详细说明如何指定列的顺序。您还应该编辑问题并包含您用于不完美结果的查询。
  • 您如何期望优化器知道6,A6,B 之后而不是在另一个6,A 之后?你如何决定顺序?
  • 数据集按照示例所示从另一个时间戳列中排序。第一行是“最旧”的时间戳,最后一行是“最新”的时间戳。

标签: sql sql-server


【解决方案1】:

假设您有一个名为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 值的最小值。然后可以使用它来分配一个顺序值作为最终结果。

【讨论】:

    猜你喜欢
    • 2015-07-16
    • 2023-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多