LEFT JOIN の定義に従うと、
- 左側のテーブルの各行に対して、右側のテーブルから一致する行が存在する場合はそれを返します
- 右側に行が存在しない場合でも、右側のテーブルのすべての列が NULL に設定された左側のテーブルから行が返されます。
ここで、exist は ON 条件と同等であり、true と評価され、すべて意味があることを理解してください。
t1.year が 2010 の行では、on 式は false と評価されます (t1.year = 2010 のすべての行で x AND 2010=2009 は false) が、左結合であるため、左側のテーブルの行が返されます。 (定義によると)。
したがって、この種の条件は、join 条件ではなく、where 条件としてのみ記述できます。
(一般的に、テーブルである必要はなく、select 式である必要があります)
編集: Erwin が興味深いことに指摘したように、 where 条件を JOIN に変えることができます
select t1.*
from t1
left outer join t2
on t1.store = t2.store
or t1.year = '2009'
where t2.store is null
なぜなら:
t1.store t1.year t2.store t1.store=t2.store t1.year=2009 join(OR)
01 2009 02 false true true
02 2009 02 true true true
03 2009 02 false true true
01 2010 02 false false false
02 2010 02 true false true
03 2010 02 false false false
したがって、上記のテーブルの結合列がfalseである行のみが t2.* フィールドに null を返します。
私が言いたかったのは、この種の条件は純粋な結合に変換できないということです。これは、左結合の方法が機能するためです (結合条件が false の場合でもレコードを返します)。結合し、逆も同様です)。
提案されたクエリについて - 私のアドバイスは、それを使用しないことです。
OR を使用したクエリは、一般的な規則として AND 条件を使用したクエリよりもパフォーマンスが低下します (OR は結果セットを拡張し、AND は制限します)。これは、join 条件と where 条件の両方に適用されます。
あなたのクエリは、where 条件で t1.year = '2009' を含むクエリよりもパフォーマンスが低下します。これは、後でインデックスを使用できるため (存在する場合)、同じように結合すると、基本的にあるテーブルのレコードを別のテーブルのレコードと人為的に結合して、where 条件が必要なレコードのみをフィルター処理するようにします。最初に 2009 年を持つ t1 からレコードのみを取得する方が効果的です (年のインデックスがあり、WHERE 条件で発生する選択性が十分に高いと仮定します)。
パフォーマンスに関するこれらの提案は両方とも、クエリ プランを調べることで検証できますし、検証する必要があります。
最後に、クエリは少しあいまいです。t1.year = '2009' の場合、結合がデカルト積になることはすぐにはわかりません (これは後で除外されます)。LEFT JOIN
そのため、シンプルでwhere t1.year = 2009 AND t2.store is null
パフォーマンスが向上し、AND が読みやすいという仮定があれば、このクエリは使用しません。