Просто внимавайте за разликата с външните съединения. Заявка, където филтър на b.IsApproved (в дясната таблица, Bar) се добавя към ON условие на JOIN :
SELECT *
FROM Foo f
LEFT OUTER JOIN Bar b ON (b.IsApproved = 1) AND (b.BarId = f.BarId);
Е НЕ същото като поставянето на филтъра в WHERE клауза:
SELECT *
FROM Foo f
LEFT OUTER JOIN Bar b ON (b.BarId = f.BarId)
WHERE (b.IsApproved = 1);
Тъй като за 'неуспешни' външни присъединявания към Bar (т.е. където няма b.BarId за f.BarId ), това ще остави b.IsApproved като NULL за всички такива неуспешни редове за присъединяване и тези редове след това ще бъдат филтрирани.
Друг начин да разгледаме това е, че за първата заявка LEFT OUTER JOIN Bar b ON (b.IsApproved = 1) AND (b.BarId = f.BarId) винаги ще връща ЛЯВИТЕ редове на таблицата, тъй като LEFT OUTER JOIN гарантира, че ЛЯВИТЕ редове на таблицата ще бъдат върнати, дори ако присъединяването е неуспешно. Въпреки това, ефектът от добавянето на (b.IsApproved = 1) към LEFT OUTER JOIN условието е да се нулират всички десни колони на таблицата, когато (b.IsApproved = 1) е невярно, т.е. съгласно същите правила, които обикновено се прилагат към LEFT JOIN условие на (b.BarId = f.BarId) .
Актуализиране :За да завършите въпроса, зададен от Конрад, еквивалентният LOJ за НЕЗАПЪЛНИТЕЛЕН филтър би бил:
SELECT *
FROM Foo f
LEFT OUTER JOIN Bar b ON (b.BarId = f.BarId)
WHERE (b.IsApproved IS NULL OR b.IsApproved = 1);
т.е. WHERE клаузата трябва да вземе предвид и двете условия дали присъединяването е неуспешно (NULL) и филтърът трябва да се игнорира, а когато свързването е успешно и филтърът трябва да се приложи. (b.IsApproved или b.BarId може да бъде тестван за NULL )
Тук съставих SqlFiddle, който демонстрира разликите между различните разположения на b.IsApproved филтър спрямо JOIN .