Nếu b là nullable, đây không phải là một lỗi. Vấn đề là SQL Server biến NOT IN thành một chuỗi <> 1 AND <> 2 AND <> 3 vv Nếu bạn có <> NULL , trả về không xác định, trong trường hợp này có nghĩa là sai. Trong các trường hợp khác nhau, điều này có thể đủ điều kiện hoặc không đủ điều kiện TẤT CẢ hàng. Thay vì LEFT JOIN cách tiếp cận, bạn nên nói:
FROM dbo.OuterTable AS t
WHERE NOT EXISTS (SELECT 1 FROM x WHERE b = t.a);
Đây là một minh chứng nhanh:
DECLARE @x TABLE(i INT);
INSERT @x VALUES(1),(2);
DECLARE @y TABLE(j INT);
INSERT @y VALUES(2),(NULL);
SELECT i FROM @x WHERE i NOT IN -- produces zero results
(SELECT j FROM @y);
SELECT i FROM @x AS x WHERE NOT EXISTS -- produces one result
(SELECT 1 FROM @y WHERE j = x.i);
Để biết thêm chi tiết (và các chỉ số để chứng minh lý do tại sao NOT EXISTS là giải pháp thay thế tốt nhất):
https://www.sqlperformance.com / 2012/12 / t-sql-queries / left-anti-semi-join
Ngoài ra, hãy đọc bài đăng trên blog này của Gail Shaw:
https://sqlinthewild. co.za/index.php/2010/02/18/not-exists-vs-not-in/