如何用Teradata实现递归更新?填充空Code字段为前序非空值
Teradata实现空Code字段填充前序非空值方案
在Teradata里处理这种空值向前填充的需求,用窗口函数是最省心高效的办法,我给你整理了完整的实现方案:
原始数据
| ID | L_nbr | Code | Description |
|---|---|---|---|
| t001 | 5 | S001 | ABCDE |
| t001 | 12 | S002 | FGHI |
| t001 | 15 | JKM | |
| t001 | 17 | NOPE | |
| t001 | 18 | S003 | RST |
| t001 | 19 | UVW | |
| t001 | 21 | S004 | ASDS34E |
| t001 | 24 | GTUS | |
| t001 | 27 | UNIF |
期望结果
| ID | L_nbr | Code | Description |
|---|---|---|---|
| t001 | 5 | S001 | ABCDE |
| t001 | 12 | S002 | FGHI |
| t001 | 15 | S002 | JKM |
| t001 | 17 | S002 | NOPE |
| t001 | 18 | S003 | RST |
| t001 | 19 | S003 | UVW |
| t001 | 21 | S004 | ASDS34E |
| t001 | 24 | S004 | GTUS |
| t001 | 27 | S004 | UNIF |
实现方案
1. 查询得到填充后的数据
如果只是需要查询出填充后的结果,直接用LAST_VALUE窗口函数即可,它支持IGNORE NULLS参数,完美适配这种向前填充的场景:
SELECT ID, L_nbr, LAST_VALUE(Code IGNORE NULLS) OVER ( PARTITION BY ID ORDER BY L_nbr ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS Code, Description FROM your_table_name;
参数说明:
LAST_VALUE(Code IGNORE NULLS):忽略Code字段的空值,自动取当前行之前最近的非空Code值PARTITION BY ID:按ID分组处理,确保只在同一个ID范围内填充前序值(多ID场景也能正确处理)ORDER BY L_nbr:按照L_nbr的数字顺序确定“前序”逻辑,保证填充的是顺序上最近的非空值ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW:明确窗口范围是从分组的第一行到当前行,确保不会取到当前行之后的值
2. 将填充结果更新回原表
如果需要把填充后的值直接更新到原表中,可以用Teradata的MERGE语句:
MERGE INTO your_table_name tgt USING ( SELECT ID, L_nbr, LAST_VALUE(Code IGNORE NULLS) OVER ( PARTITION BY ID ORDER BY L_nbr ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) AS new_code FROM your_table_name ) src ON tgt.ID = src.ID AND tgt.L_nbr = src.L_nbr WHEN MATCHED AND tgt.Code IS NULL THEN UPDATE SET tgt.Code = src.new_code;
这个语句会只更新原表中Code为空的记录,把它们替换成填充后的非空值,不会改动已经有值的记录。
内容的提问来源于stack exchange,提问作者vinothbabu
相关产品推荐
相关产品推荐

