外部結合との違いに注意してください。の条件にb.IsApproved(右の表のバー)のフィルターが追加されたクエリ:ONJOIN
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);
「失敗した」外部結合(つまり、 aBarがない場所) の場合、これはそのような失敗したすべての結合行として残され、これらの行はフィルターで除外されます。b.BarIdf.BarIdb.IsApprovedNULL
別の見方をすると、結合が失敗した場合でも LEFT テーブルの行が返されることが保証されているため、最初のクエリでLEFT OUTER JOIN Bar b ON (b.IsApproved = 1) AND (b.BarId = f.BarId)は常にLEFT テーブルの行が返されるということです。LEFT OUTER JOINただし、 on 条件に追加(b.IsApproved = 1)すると、が false のLEFT OUTER JOIN場合に右のテーブル列が NULL になります。つまり、条件 on に(b.IsApproved = 1)通常適用されるのと同じ規則に従います。LEFT JOIN(b.BarId = f.BarId)
更新: コンラッドが尋ねた質問を完了するには、OPTIONAL フィルターの同等の 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.