外部結合との違いに注意してください。 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
に関連するフィルター 。