我目前有一个表格,其中每个组的交易都按顺序排序,如下所示:
| 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)。所以目标是这样的一个表:
| 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
。
典型的解决方案包括对记录进行排名并执行窗口总和。当总排名与窗口总和之间的差异发生变化时,将开始一个新的组。
请考虑以下查询:
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 |值-:| -------------:| ----:1 | 1 | 82 | 2 | 3433 | 3 | 284 | 4 | 1025 | 1 | 306 | 2 | 57 | 3 | 1008 | 1 | 129 | 2 | 1610 | 3 | 2811 | 4 | 15712 | 5 | 125
查询返回:
id | transaction_no |价值| grp-:| -------------:| ----:| ---:1 | 1 | 8 | 10012 | 2 | 343 | 10013 | 3 | 28 | 10014 | 4 | 102 | 10015 | 1 | 30 | 10026 | 2 | 5 | 10027 | 3 | 100 | 10028 | 1 | 12 | 10039 | 2 | 16 | 100310 | 3 | 28 | 100311 | 4 | 157 | 100312 | 5 | 125 | 1003