SQL技术需求:按条件复制前一行并新增状态为New的行
没问题,我来帮你搞定这个需求!先把原数据、完整的期望结果以及实现方案整理清楚:
原输入数据表
| ID | status | message | set |
|---|---|---|---|
| 1 | Completed | step1 | 1 |
| 2 | Completed | step2 | 1 |
| 3 | Failed | step3 | 1 |
| 4 | Completed | step1 | 2 |
| 5 | Completed | step2 | 2 |
| 6 | Failed | step3 | 2 |
需求说明
针对每个set分组,若分组内存在Failed状态的步骤,则复制该Failed步骤的前一行数据,新增一行并将status字段设置为"New"。
完整期望结果表
按照需求逻辑,每个set里的Failed步骤(ID3和ID6)的前一行分别是ID2和ID5,所以新增两行后,最终表如下:
| ID | status | message | set |
|---|---|---|---|
| 1 | Completed | step1 | 1 |
| 2 | Completed | step2 | 1 |
| 3 | Failed | step3 | 1 |
| 7 | New | step2 | 1 |
| 4 | Completed | step1 | 2 |
| 5 | Completed | step2 | 2 |
| 6 | Failed | step3 | 2 |
| 8 | New | step2 | 2 |
实现方案(SQL)
我们可以利用窗口函数LAG()来精准定位每个Failed步骤的前一行数据,再将原表数据与新增的"New"状态行合并,代码如下:
WITH failed_previous_rows AS ( SELECT -- 生成唯一的新ID:原表最大ID加上分组内的行号,保证ID不重复 (SELECT MAX(ID) FROM your_table) + ROW_NUMBER() OVER () AS ID, 'New' AS status, -- 获取当前Failed行的上一行的message值 LAG(message) OVER (PARTITION BY set ORDER BY ID) AS message, set FROM your_table WHERE status = 'Failed' ) -- 合并原表数据和新增的New行,按set和ID排序 SELECT * FROM your_table UNION ALL SELECT * FROM failed_previous_rows ORDER BY set, ID;
关键细节说明:
LAG(message) OVER (PARTITION BY set ORDER BY ID):按set分组、ID排序,直接拿到Failed步骤的前一行的message内容,完美匹配需求里的"复制前一行数据"。- 新ID的生成方式可以根据你的实际场景调整,如果你的表有自增ID,也可以让数据库自动生成,这里用原表最大ID加行号是为了确保ID唯一且有序。
UNION ALL会保留原表的所有行,再加上新增的行,最后排序后就是我们要的结果。
内容的提问来源于stack exchange,提问作者Raghav D
相关产品推荐
相关产品推荐

