SQL问题:基于前序记录与Code=B条件更新UpdatedAmount字段
解决方案:处理依赖前序更新值的字段计算
问题背景
需求规则:
- 当
Code为B时,UpdatedAmount替换为对应后续非B行的RunningTotal值 - 当
Code不为B时,UpdatedAmount保持原有值
使用LEAD()函数无法满足需求,因为该函数仅能读取原始数据集的前序值,无法引用计算后的字段结果。
当前输出(LEAD()实现)
| Id | SNO | Rank | Amount | RunningTotal | Code | UpdatedAmount |
|---|---|---|---|---|---|---|
| 1 | ABC01 | 4 | 0 | 0 | A | 0 |
| 1 | ABC02 | 3 | 0 | 0 | B | 4 |
| 1 | ABC03 | 2 | 4 | 4 | B | 8 |
| 1 | ABC04 | 1 | 4 | 8 | B | Null |
期望输出
| Id | SNO | Rank | Amount | RunningTotal | Code | UpdatedAmount |
|---|---|---|---|---|---|---|
| 1 | ABC01 | 4 | 0 | 0 | A | 0 |
| 1 | ABC02 | 3 | 0 | 0 | B | 8 |
| 1 | ABC03 | 2 | 4 | 4 | B | 8 |
| 1 | ABC04 | 1 | 4 | 8 | A | 8 |
实现方案
使用窗口函数分组标记+聚合的方式,解决依赖后续非B行值的问题:
WITH grouped_data AS ( SELECT *, -- 按Rank升序排序,每遇到非B行就生成新组ID SUM(CASE WHEN Code <> 'B' THEN 1 ELSE 0 END) OVER (ORDER BY Rank ASC) AS group_id FROM your_table ) SELECT Id, SNO, Rank, Amount, RunningTotal, Code, -- 组内取非B行的RunningTotal,B行自动继承该值 MAX(CASE WHEN Code <> 'B' THEN RunningTotal END) OVER (PARTITION BY group_id) AS UpdatedAmount FROM grouped_data ORDER BY Rank DESC; -- 保持原输出的排序顺序
逻辑说明
- 分组标记:通过
SUM() OVER()窗口函数,以Rank升序(Rank越小越靠后)为顺序,每遇到Code不为B的行,组ID加1,将连续的B行归到同一个组中。 - 聚合取值:在每个分组内,用
MAX()函数提取非B行的RunningTotal,该值会自动填充到同组所有B行的UpdatedAmount字段,非B行则保留自身的RunningTotal。
内容的提问来源于stack exchange,提问作者sreeja
相关产品推荐
相关产品推荐

