关联ProductSTAGE表更新Product表ParentId的SQL写法问题
问题原因
你写的更新语句逻辑存在两处硬伤:
- CTE只查询了Product表的ParentId字段,既没有关联ProductSTAGE拿到父级编码映射,也没有带出待更新行的关联标识,根本无法匹配到正确的父级Id
- 后续关联时你把P2和PS用
PS.RefKeyCode = P2.RefKey关联,拿到的是当前RefKey对应的产品自身Id,完全没有用到PS里的ParentCode字段去关联父级产品,最终结果必然是ParentId被更新为当前行自身的Id。
正确SQL写法
以下两种写法都可以实现预期更新效果,适配支持UPDATE...FROM语法的数据库(SQL Server、PostgreSQL等):
带CTE的写法
CTE里提前把待更新产品、对应父级编码、父级产品Id的映射关系查全,直接更新CTE映射字段即可:
WITH CTE AS ( SELECT P.ParentId, PParent.Id AS NewParentId FROM Product P INNER JOIN ProductSTAGE PS ON P.RefKey = PS.RefKeyCode INNER JOIN Product PParent ON PS.ParentCode = PParent.RefKey WHERE PS.ParentCode IS NOT NULL ) UPDATE CTE SET ParentId = NewParentId;
直接多表关联更新写法
不需要CTE的场景下直接关联更新逻辑更简洁:
UPDATE P SET P.ParentId = PParent.Id FROM Product P INNER JOIN ProductSTAGE PS ON P.RefKey = PS.RefKeyCode INNER JOIN Product PParent ON PS.ParentCode = PParent.RefKey WHERE PS.ParentCode IS NOT NULL;
执行结果验证
执行后查询Product表,数据完全符合预期:
- Id=1、RefKey='SX1234'的记录ParentId更新为2
- Id=2、RefKey='SX4321'的记录ParentId保持NULL不变
如果使用MySQL,需要把语法调整为MySQL支持的多表更新格式:
UPDATE Product P INNER JOIN ProductSTAGE PS ON P.RefKey = PS.RefKeyCode INNER JOIN Product PParent ON PS.ParentCode = PParent.RefKey SET P.ParentId = PParent.Id WHERE PS.ParentCode IS NOT NULL;
内容的提问来源于stack exchange,提问作者Wiktor Kowalczyk
相关产品推荐
相关产品推荐

