Tylko uważaj na różnicę z połączeniami zewnętrznymi. Zapytanie, w którym filtr b.IsApproved (w prawej tabeli, Bar) jest dodany do ON warunek JOIN :
SELECT *
FROM Foo f
LEFT OUTER JOIN Bar b ON (b.IsApproved = 1) AND (b.BarId = f.BarId);
Jest NIE tak samo jak umieszczenie filtra w WHERE klauzula:
SELECT *
FROM Foo f
LEFT OUTER JOIN Bar b ON (b.BarId = f.BarId)
WHERE (b.IsApproved = 1);
Ponieważ dla 'failed' zewnętrznych łączy do Bar (tzn. tam, gdzie nie ma b.BarId dla f.BarId ), spowoduje to pozostawienie b.IsApproved jako NULL dla wszystkich takich nieudanych wierszy sprzężenia, a następnie zostaną one odfiltrowane.
Innym sposobem patrzenia na to jest to, że dla pierwszego zapytania LEFT OUTER JOIN Bar b ON (b.IsApproved = 1) AND (b.BarId = f.BarId) zawsze zwróci LEFT wiersze tabeli, ponieważ LEFT OUTER JOIN gwarantuje, że LEFT wiersze tabeli zostaną zwrócone, nawet jeśli łączenie się nie powiedzie. Jednak efekt dodania (b.IsApproved = 1) do LEFT OUTER JOIN warunkiem jest NULL wszystkich prawych kolumn tabeli, gdy (b.IsApproved = 1) jest fałszywe, tj. zgodnie z tymi samymi zasadami, które zwykle stosuje się do LEFT JOIN warunek na (b.BarId = f.BarId) .
Aktualizacja :Aby uzupełnić pytanie zadane przez Conrada, odpowiednikiem LOJ dla filtra OPCJONALNEGO byłoby:
SELECT *
FROM Foo f
LEFT OUTER JOIN Bar b ON (b.BarId = f.BarId)
WHERE (b.IsApproved IS NULL OR b.IsApproved = 1);
czyli WHERE Klauzula musi uwzględniać oba warunki, czy łączenie się nie powiedzie (NULL) a filtr ma zostać zignorowany, a gdzie łączenie się powiedzie, a filtr musi zostać zastosowany. (b.IsApproved lub b.BarId można przetestować pod kątem NULL )
Umieściłem tutaj SqlFiddle, który pokazuje różnice między różnymi miejscami b.IsApproved filtr względem JOIN .