向有序交易组添加唯一 ID

Add unique id to groups of ordered transactions

我目前有一个 table,每个组的交易顺序如下:

| transaction_no | value |
|----------------|-------|
|              1 |     8 |
|              2 |   343 |
|              3 |    28 |
|              4 |   102 |
|              1 |    30 |
|              2 |     5 |
|              3 |   100 |
|              1 |    12 |
|              2 |    16 |
|              3 |    28 |
|              4 |   157 |
|              5 |   125 |

但是我有兴趣添加另一列,为每个列分配一个唯一的 ID 分组(transaction_no 以 1 开始并以 x 结束的交易集 其中紧跟在 x 之后的 transaction_no 是 1)。所以目标是这样的 table:

| transaction_no | value | stmt_id |
|----------------|-------|---------|
|              1 |     8 |    1001 |
|              2 |   343 |    1001 |
|              3 |    28 |    1001 |
|              4 |   102 |    1001 |
|              1 |    30 |    1002 |
|              2 |     5 |    1002 |
|              3 |   100 |    1002 |
|              1 |    12 |    1003 |
|              2 |    16 |    1003 |
|              3 |    28 |    1003 |
|              4 |   157 |    1003 |
|              5 |   125 |    1003 |

我该怎么做?

这是间隙和孤岛问题的变体。为了使其可解决,正如 Gordon Linoff 所评论的那样,您需要一个可用于对行进行排序的列。我假设存在这样一个列并称为 id.

典型的解决方案涉及对记录进行排名并执行 window 求和。当总排名与 window 总和之间的差异发生变化时,新组开始。

考虑以下查询:

select 
    id,
    transaction,
    value, 
    1000 
        + rn 
        - sum(case when transaction_no = lag_transaction_no + 1 then 1 else 0 end) 
            over(order by id) grp
from (
    select 
        t.*,
        row_number() over(order by id) rn,
        lag(transaction_no) over(order by id) lag_transaction_no
    from mytable t
) t

使用此样本数据:

id | transaction_no | value
-: | -------------: | ----:
 1 |              1 |     8
 2 |              2 |   343
 3 |              3 |    28
 4 |              4 |   102
 5 |              1 |    30
 6 |              2 |     5
 7 |              3 |   100
 8 |              1 |    12
 9 |              2 |    16
10 |              3 |    28
11 |              4 |   157
12 |              5 |   125

查询returns:

id | transaction_no | value |  grp
-: | -------------: | ----: | ---:
 1 |              1 |     8 | 1001
 2 |              2 |   343 | 1001
 3 |              3 |    28 | 1001
 4 |              4 |   102 | 1001
 5 |              1 |    30 | 1002
 6 |              2 |     5 | 1002
 7 |              3 |   100 | 1002
 8 |              1 |    12 | 1003
 9 |              2 |    16 | 1003
10 |              3 |    28 | 1003
11 |              4 |   157 | 1003
12 |              5 |   125 | 1003

Demo on SQL Server 2012 DB Fiddle