Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

Mệnh đề WHERE so với ON khi sử dụng JOIN

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 .



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kết nối với MS SQL Server bằng Xác thực Windows bằng Python?

  2. EF 6 - Cách thực hiện chính xác các truy vấn song song

  3. Lỗi SSMS 2016 khi nhập bacpac Azure SQL v12:không hỗ trợ khóa chính không có mật khẩu

  4. Khi hiệu suất của Distinction và Group By khác nhau?

  5. T-SQL:Làm tròn đến khoảng thời gian 15 phút gần nhất