Berhati-hatilah dengan perbedaan dengan gabungan luar. Kueri di mana filter b.IsApproved (di tabel kanan, Bar) ditambahkan ke ON kondisi JOIN :
SELECT *
FROM Foo f
LEFT OUTER JOIN Bar b ON (b.IsApproved = 1) AND (b.BarId = f.BarId);
Apakah TIDAK sama dengan menempatkan filter di WHERE klausa:
SELECT *
FROM Foo f
LEFT OUTER JOIN Bar b ON (b.BarId = f.BarId)
WHERE (b.IsApproved = 1);
Karena untuk 'gagal' luar bergabung ke Bar (yaitu di mana tidak ada b.BarId untuk f.BarId ), ini akan meninggalkan b.IsApproved sebagai NULL untuk semua baris gabungan yang gagal tersebut, dan baris ini kemudian akan disaring.
Cara lain untuk melihat ini adalah bahwa untuk kueri pertama, LEFT OUTER JOIN Bar b ON (b.IsApproved = 1) AND (b.BarId = f.BarId) akan selalu mengembalikan baris tabel KIRI, karena LEFT OUTER JOIN menjamin baris tabel KIRI akan dikembalikan bahkan jika gabungan gagal. Namun, efek penambahan (b.IsApproved = 1) ke LEFT OUTER JOIN dengan syarat adalah NULL kolom tabel kanan saat (b.IsApproved = 1) salah, yaitu sesuai dengan aturan yang sama yang biasanya diterapkan pada LEFT JOIN kondisi pada (b.BarId = f.BarId) .
Perbarui :Untuk menyelesaikan pertanyaan yang diajukan oleh Conrad, LOJ yang setara untuk filter OPSIONAL adalah:
SELECT *
FROM Foo f
LEFT OUTER JOIN Bar b ON (b.BarId = f.BarId)
WHERE (b.IsApproved IS NULL OR b.IsApproved = 1);
yaitu WHERE klausa perlu mempertimbangkan kedua kondisi apakah penggabungan gagal (NULL) dan filter harus diabaikan, dan di mana gabungan berhasil dan filter harus diterapkan. (b.IsApproved atau b.BarId dapat diuji untuk NULL )
Saya telah menggabungkan SqlFiddle di sini yang menunjukkan perbedaan antara berbagai penempatan b.IsApproved filter relatif terhadap JOIN .