外部結合との違いに注意してください。 b.IsApprovedのフィルターが存在するクエリ (右側のテーブルのバー)が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);
'failed'の場合、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なので、常にLEFTテーブルの行を返します。 結合が失敗した場合でも、LEFTテーブルの行が返されることを保証します。ただし、(b.IsApproved = 1)を追加した場合の効果 LEFT OUTER JOINへ 条件は、(b.IsApproved = 1)の場合、右側のテーブル列をNULLにすることです。 はfalseです。つまり、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に関連するフィルター 。