Chỉ cần cẩn thận về sự khác biệt với các mối nối bên ngoài. Một truy vấn trong đó bộ lọc b.IsApproved (trên bảng bên phải, Thanh) được thêm vào ON điều kiện của JOIN :
SELECT *
FROM Foo f
LEFT OUTER JOIN Bar b ON (b.IsApproved = 1) AND (b.BarId = f.BarId);
KHÔNG giống như đặt bộ lọc trong WHERE mệnh đề:
SELECT *
FROM Foo f
LEFT OUTER JOIN Bar b ON (b.BarId = f.BarId)
WHERE (b.IsApproved = 1);
Vì cho các phép nối bên ngoài 'không thành công' vào Bar (tức là không có b.BarId cho một f.BarId ), điều này sẽ để lại b.IsApproved dưới dạng NULL cho tất cả các hàng nối không thành công như vậy, và các hàng này sau đó sẽ được lọc ra.
Một cách khác để xem xét vấn đề này là đối với truy vấn đầu tiên, LEFT OUTER JOIN Bar b ON (b.IsApproved = 1) AND (b.BarId = f.BarId) sẽ luôn trả về các hàng của bảng TRÁI, vì LEFT OUTER JOIN đảm bảo các hàng của bảng TRÁI sẽ được trả về ngay cả khi phép nối không thành công. Tuy nhiên, ảnh hưởng của việc thêm (b.IsApproved = 1) vào LEFT OUTER JOIN với điều kiện là NULL bất kỳ cột bên phải nào trong bảng khi (b.IsApproved = 1) là sai, tức là theo các quy tắc tương tự thường được áp dụng cho LEFT JOIN điều kiện trên (b.BarId = f.BarId) .
Cập nhật :Để hoàn thành câu hỏi do Conrad hỏi, LOJ tương đương cho bộ lọc TÙY CHỌN sẽ là:
SELECT *
FROM Foo f
LEFT OUTER JOIN Bar b ON (b.BarId = f.BarId)
WHERE (b.IsApproved IS NULL OR b.IsApproved = 1);
tức là WHERE mệnh đề cần phải xem xét cả điều kiện cho dù kết nối không thành công (NULL) và bộ lọc sẽ bị bỏ qua và nơi nối thành công và bộ lọc phải được áp dụng. (b.IsApproved hoặc b.BarId có thể được kiểm tra cho NULL )
Tôi đã đặt một SqlFiddle lại với nhau ở đây để thể hiện sự khác biệt giữa các vị trí khác nhau của b.IsApproved bộ lọc liên quan đến JOIN .