Greenplum 4.3.23.0缺失值填充:补全y_id连续值的SQL需求
解决Greenplum中补全连续y_id的SQL方案
嘿,我来帮你搞定这个补全连续y_id的需求!先明确下你的场景:原表中同一分组(ID, ID2, Code, Type_ID, Status)内的y_id存在断档,需要补全中间缺失的数值,新增的记录Latest_flag设为Y,原有记录保留原有的Latest_flag值。
原数据表
| ID | ID2 | Code | Type_ID | Status | y_id | Latest_flag |
|---|---|---|---|---|---|---|
| 10 | 10001 | 205 | 7 | P | 114 | Y |
| 10 | 10001 | 205 | 7 | P | 116 | NULL |
| 10 | 10002 | 205 | 6 | P | 116 | Y |
| 10 | 10002 | 205 | 6 | P | 120 | Y |
期望输出
| ID | ID2 | Code | Type_ID | Status | y_id | Latest_flag |
|---|---|---|---|---|---|---|
| 10 | 10001 | 205 | 7 | P | 114 | Y |
| 10 | 10001 | 205 | 7 | P | 115 | Y |
| 10 | 10001 | 205 | 7 | P | 116 | NULL |
| 10 | 10002 | 205 | 6 | P | 116 | Y |
| 10 | 10002 | 205 | 6 | P | 117 | Y |
| 10 | 10002 | 205 | 6 | P | 118 | Y |
| 10 | 10002 | 205 | 6 | P | 119 | Y |
| 10 | 10002 | 205 | 6 | P | 120 | Y |
实现SQL
Greenplum 4.3.23.0支持递归CTE(公共表表达式),我们可以用它来生成连续的y_id,再和原表关联补全字段:
WITH RECURSIVE group_ranges AS ( -- 第一步:获取每个分组的y_id范围(最小、最大值) SELECT ID, ID2, Code, Type_ID, Status, MIN(y_id) AS min_y, MAX(y_id) AS max_y FROM your_table_name -- 替换成你的实际表名 GROUP BY ID, ID2, Code, Type_ID, Status ), recursive_y AS ( -- 递归起始:每个分组的最小y_id SELECT ID, ID2, Code, Type_ID, Status, min_y AS y_id FROM group_ranges UNION ALL -- 递归生成后续连续y_id,直到达到分组的max_y SELECT r.ID, r.ID2, r.Code, r.Type_ID, r.Status, ry.y_id + 1 FROM recursive_y ry JOIN group_ranges r ON ry.ID = r.ID AND ry.ID2 = r.ID2 AND ry.Code = r.Code AND ry.Type_ID = r.Type_ID AND ry.Status = r.Status WHERE ry.y_id < r.max_y ) -- 关联原表,填充Latest_flag字段 SELECT ry.ID, ry.ID2, ry.Code, ry.Type_ID, ry.Status, ry.y_id, COALESCE(t.Latest_flag, 'Y') AS Latest_flag FROM recursive_y ry LEFT JOIN your_table_name t ON -- 同样替换成实际表名 ry.ID = t.ID AND ry.ID2 = t.ID2 AND ry.Code = t.Code AND ry.Type_ID = t.Type_ID AND ry.Status = t.Status AND ry.y_id = t.y_id ORDER BY ry.ID, ry.ID2, ry.y_id;
逻辑说明
- group_ranges CTE:先按分组维度聚合,得到每个分组内y_id的最小和最大值,确定需要补全的数值范围。
- recursive_y CTE:递归生成每个分组内从
min_y到max_y的所有连续y_id——起始行是分组的最小y_id,之后每次递归把y_id加1,直到达到最大值。 - 最终查询:将递归生成的所有连续y_id记录和原表左连接,用
COALESCE函数处理Latest_flag:如果是原表已有的记录,保留原字段值;如果是新增的补全记录,自动设为Y。最后按ID、ID2、y_id排序,得到符合要求的结果。
内容的提问来源于stack exchange,提问作者krux




