SQL连接两张表更新多列时更新行数不符的问题排查
问题排查与解决方案
嘿,这个问题我太熟了——你的UPDATE语句没有加上WHERE子句来限定只更新匹配的记录,这就是为什么整个表的200条都被修改了,而不是你预期的31条!
问题根源
当前的写法是对SRC表的每一行都执行SET操作,不管它有没有在LKP表中找到匹配的记录:
- 对于能匹配到
LKP的31条行,子查询会返回对应的lkp.A/B/C和固定值'1',这部分是符合你预期的更新; - 对于剩下的169条不匹配的行,子查询会返回空结果,这时候赋值操作会把
src.A、src.B、src.C设为NULL,src.D设为'1'——相当于所有行都被更新了,哪怕它们不符合src.id_1=lkp.id_1 and src.CC=lkp.CC的匹配条件。
修正方案
根据你使用的数据库,有两种常用的修正写法:
方案1:用WHERE EXISTS过滤(通用多数数据库)
这种写法先通过EXISTS子查询筛选出真正匹配的行,再执行更新:
UPDATE SRC src SET (src.A, src.B, src.C, src.D) = ( SELECT lkp.A, lkp.B, lkp.C, '1' FROM LKP lkp WHERE src.id_1 = lkp.id_1 AND src.CC = lkp.CC ) WHERE EXISTS ( SELECT 1 FROM LKP lkp WHERE src.id_1 = lkp.id_1 AND src.CC = lkp.CC );
方案2:用UPDATE ... JOIN语法(MySQL/SQL Server等支持的数据库)
这种写法直接通过JOIN关联两张表,只会更新匹配的行,逻辑更直观:
-- MySQL/SQL Server 适用 UPDATE src SET src.A = lkp.A, src.B = lkp.B, src.C = lkp.C, src.D = '1' FROM SRC src INNER JOIN LKP lkp ON src.id_1 = lkp.id_1 AND src.CC = lkp.CC;
验证建议
执行UPDATE之前,你可以先跑下面的查询确认筛选出的行数是否为31,避免误操作:
SELECT COUNT(*) FROM SRC src WHERE EXISTS ( SELECT 1 FROM LKP lkp WHERE src.id_1 = lkp.id_1 AND src.CC = lkp.CC );
内容的提问来源于stack exchange,提问作者Yogee yadav
相关产品推荐
相关产品推荐

