如何用SQL获取表中列值每次变化的首次出现记录?
提取状态变更的首次出现记录(基于LAG函数实现)
完全可以用LAG()函数解决这个问题,核心思路是对比每条记录与同ID上一条记录的状态,筛选出状态发生变化(或为该ID第一条记录)的行,这些就是状态变更后的首次出现记录。
解决方案SQL代码
假设你的表名为status_log,执行以下查询:
SELECT ID, Status, Time FROM ( SELECT ID, Status, Time, -- 按ID分组、时间排序,获取上一条记录的状态 LAG(Status) OVER (PARTITION BY ID ORDER BY Time) AS prev_status FROM status_log ) AS status_with_prev -- 保留第一条记录,或与上一条状态不同的记录 WHERE prev_status IS NULL OR prev_status != Status ORDER BY ID, Time;
逻辑解释
- LAG函数的作用:
LAG(Status) OVER (PARTITION BY ID ORDER BY Time)会为每条记录生成一个prev_status字段,存储同ID下按时间顺序的上一条记录的状态。 - 过滤条件:
prev_status IS NULL:匹配每个ID的第一条记录(没有上一条记录,必然是状态的首次出现)prev_status != Status:匹配当前状态与上一条状态不同的记录,也就是状态变更后的首次出现记录
- 排序:最终结果按ID和时间排序,保证顺序符合状态变更的时间线。
验证示例数据
将你提供的示例数据代入查询,子查询生成的prev_status列如下:
| ID | Status | Time | prev_status |
|---|---|---|---|
| 1 | Open | 2022-07-01 12:00 | NULL |
| 1 | Open | 2022-07-01 18:00 | Open |
| 1 | In Progress | 2022-07-02 12:00 | Open |
| 1 | Open | 2022-07-02 18:00 | In Progress |
| 1 | Closed | 2022-07-03 12:00 | Open |
过滤后保留的行就是你需要的结果,完全符合预期。
内容的提问来源于stack exchange,提问作者user1111
相关产品推荐
相关产品推荐

