SQL Server中如何正确获取两次查询间的183条差异记录?
问题澄清与解决方案
核心误解
你提到的11196 - 11013 = 183是查询结果的行数差值,而非all14020612中未匹配关联记录的实际数量。原因是INNER JOIN查询会生成重复行:当all14020612中的单条记录对应MoshaverinAmlaks和Users表中的多条关联组合时,每条组合都会生成一行结果,导致INNER JOIN的总行数大于实际匹配的all14020612记录数。
你的NOT EXISTS查询返回380条,这其实是all14020612中完全没有对应关联记录的真实数量。如果你的目标确实是获取这部分记录,以下是更严谨的写法;如果你确实需要183条,那需要重新明确需求(比如是获取匹配后行数与原表的差异行,但这通常没有业务意义)。
正确获取未匹配记录的SQL
方法1:优化NOT EXISTS逻辑
避免子查询中不必要的冗余,直接检查关联条件:
SELECT * FROM all14020612 AS a WHERE NOT EXISTS ( SELECT 1 FROM MoshaverinAmlaks AS m INNER JOIN Users AS u ON m.Code = u.MoshaverinAmlakCode WHERE m.SenfID = a.[شناسه صنفی] COLLATE SQL_Latin1_General_CP1256_CI_AS )
注:你原有的NOT EXISTS写法逻辑本身正确,返回380条是真实的未匹配记录数。若结果不符合预期,需检查关联条件的正确性,比如COLLATE规则是否匹配,或是否存在数据重复情况。
方法2:使用LEFT JOIN + IS NULL
通过左连接筛选未匹配的记录,同时提前去重以避免干扰:
SELECT a.* FROM all14020612 AS a LEFT JOIN ( -- 先获取所有有对应Users记录的MoshaverinAmlaks的SenfID SELECT DISTINCT m.SenfID FROM MoshaverinAmlaks AS m INNER JOIN Users AS u ON m.Code = u.MoshaverinAmlakCode ) AS matched_senf ON matched_senf.SenfID = a.[شناسه صنفی] COLLATE SQL_Latin1_General_CP1256_CI_AS WHERE matched_senf.SenfID IS NULL
验证匹配记录数
若想确认all14020612中实际有多少条记录能关联到后续表,可以运行:
SELECT COUNT(DISTINCT a.[شناسه صنفی]) -- 假设[شناسه صنفی]是表的唯一标识列 FROM all14020612 AS a INNER JOIN MoshaverinAmlaks AS m ON a.[شناسه صنفی] COLLATE SQL_Latin1_General_CP1256_CI_AS = m.SenfID INNER JOIN Users AS u ON m.Code = u.MoshaverinAmlakCode
计算11196 - 该结果,应该等于你的NOT EXISTS查询返回的380条,这说明数据本身的匹配情况就是如此。
内容的提问来源于stack exchange,提问作者PEDRAM POURHAKIM
相关产品推荐
相关产品推荐

