如何为每个FK_ID插入缺失的PLANNED/DOING/DONE状态行?
解决方案
核心思路是先生成所有FK_ID与三种状态的全量组合,再和原表关联补全已有数据,缺失的状态行自然会用NULL填充Updated_Date。
假设你的原表名为task_status,以下是具体实现:
标准SQL实现(支持CTE语法)
-- 生成全量组合:每个FK_ID对应PLANNED、DOING、DONE WITH all_statuses AS ( SELECT 'PLANNED' AS Name UNION ALL SELECT 'DOING' UNION ALL SELECT 'DONE' ), unique_fk AS ( SELECT DISTINCT FK_ID FROM task_status ) SELECT uf.FK_ID, as_.Name, ts.Updated_Date FROM unique_fk uf CROSS JOIN all_statuses as_ LEFT JOIN task_status ts ON uf.FK_ID = ts.FK_ID AND as_.Name = ts.Name ORDER BY uf.FK_ID, as_.Name;
问题原因说明
你之前的方法只做了临时状态表与原表的LEFT JOIN,仅能补全全表都不存在的状态,但无法处理「某个FK_ID缺特定状态但其他FK_ID有该状态」的场景。必须通过CROSS JOIN生成每个FK_ID和所有状态的组合,才能确保每个FK_ID都拥有三种状态的完整行。
兼容旧版SQL(无CTE支持)
如果你的数据库不支持WITH子句(如MySQL 5.x),可以用临时表+子查询实现:
-- 创建临时状态表 CREATE TEMPORARY TABLE temp_statuses (Name VARCHAR(20)); INSERT INTO temp_statuses VALUES ('PLANNED'), ('DOING'), ('DONE'); -- 生成全量组合并关联原表 SELECT uf.FK_ID, ts.Name, t.Updated_Date FROM (SELECT DISTINCT FK_ID FROM task_status) uf CROSS JOIN temp_statuses ts LEFT JOIN task_status t ON uf.FK_ID = t.FK_ID AND ts.Name = t.Name ORDER BY uf.FK_ID, ts.Name;
结果验证
执行后每个FK_ID都会对应三行记录:
- 原表已存在的状态行,保留原
Updated_Date值 - 原表缺失的状态行,
Updated_Date自动填充为NULL
内容的提问来源于stack exchange,提问作者rball
相关产品推荐
相关产品推荐

