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):
http://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:
http://sqlinthewild. co.za/index.php/2010/02/18/not-exists-vs-not-in/