MSSQL中用内连接与左外连接实现表数据筛选插入问题排查
解决T1中不存在于T2的数据插入T3的问题
我来帮你搞定这个需求!你想要把T1里有但T2中没有的记录插入到T3,先看看你原来的SQL哪里出问题了:
你的原SQL里用了INNER JOIN T2,这一步直接把T2中没有匹配Id的T1记录过滤掉了,后面再做LEFT JOIN也拿不到目标数据,逻辑完全走偏了。下面给你几个靠谱的解决方案:
方法1:LEFT JOIN + IS NULL(最直观的写法)
INSERT INTO T3 (Id, AccountId, Name) SELECT T1.Id, T1.AccountId, T1.Name FROM T1 LEFT JOIN T2 ON T1.Id = T2.Id WHERE T2.Id IS NULL AND T1.AccountId = 5555;
原理:LEFT JOIN会保留T1的所有记录,对于T2中没有对应Id的行,T2的所有列都会是NULL,通过T2.Id IS NULL就能精准筛选出T1独有的记录。
方法2:NOT EXISTS(性能友好的写法)
INSERT INTO T3 (Id, AccountId, Name) SELECT Id, AccountId, Name FROM T1 WHERE AccountId = 5555 AND NOT EXISTS ( SELECT 1 FROM T2 WHERE T2.Id = T1.Id );
原理:NOT EXISTS会检查T2中是否不存在和当前T1.Id匹配的记录,这种写法在Id字段有索引时,性能通常比LEFT JOIN更好,因为数据库可以快速定位不存在的匹配项。
方法3:EXCEPT(简洁的集合操作写法)
如果你的SQL Server版本支持(基本2008及以上都支持),可以用集合操作来实现:
INSERT INTO T3 (Id, AccountId, Name) SELECT Id, AccountId, Name FROM T1 WHERE AccountId = 5555 EXCEPT SELECT Id, AccountId, Name FROM T2;
原理:EXCEPT会返回第一个查询结果中存在,但第二个查询结果中没有的记录,注意两个查询的列数、类型必须完全匹配,而且EXCEPT会自动去重,如果你的数据没有重复项,这个写法非常简洁。
用上面任意一种方法,都能得到你想要的结果:把T1中Id=122的David记录插入到T3里。
内容的提问来源于stack exchange,提问作者Bettlerl8




