更新:
私のブログのこれらの記事では、方法の違いについて詳しく説明しています。
-
NOT IN
vs.存在しない
vs.LEFT JOIN / IS NULL
:SQL Server
-
NOT IN
vs.存在しない
vs.LEFT JOIN / IS NULL
:PostgreSQL
-
NOT IN
vs.存在しない
vs.LEFT JOIN / IS NULL
:Oracle
-
NOT IN
vs.存在しない
vs.LEFT JOIN / IS NULL
:MySQL
このようなクエリを実行するには、次の3つの方法があります。
-
LEFT JOIN / IS NULL
:SELECT * FROM common LEFT JOIN table1 t1 ON t1.common_id = common.common_id WHERE t1.common_id IS NULL
-
存在しません
:SELECT * FROM common WHERE NOT EXISTS ( SELECT NULL FROM table1 t1 WHERE t1.common_id = common.common_id )
-
NOT IN
:SELECT * FROM common WHERE common_id NOT IN ( SELECT common_id FROM table1 t1 )
table1.common_id
の場合 null許容型ではなく、これらのクエリはすべて意味的に同じです。
null許容の場合、 NOT IN
IN
なので、違います (したがって、 NOT IN
) NULL
を返します 値がNULL
を含むリストのいずれにも一致しない場合 。
これは紛らわしいかもしれませんが、これの代替構文を思い出すと、より明白になる可能性があります:
common_id = ANY
(
SELECT common_id
FROM table1 t1
)
この条件の結果は、リスト内のすべての比較のブール積です。もちろん、単一の NULL
値はNULL
を生成します 結果全体をレンダリングする結果NULL
common_id
と明確に言うことはできません。 値の少なくとも1つがNULL
であるため、はこのリストのいずれにも等しくありません。 。
次のデータがあるとします。
common
--
1
3
table1
--
NULL
1
2
LEFT JOIN / IS NULL
およびNOTEXISTS
3
を返します 、 NOT IN
何も返さない (常に FALSE
のいずれかに評価されるため またはNULL
。
MySQL
で 、null許容でない列の場合、 LEFT JOIN / IS NULL
およびNOTIN
NOT EXISTS
よりも少し(数パーセント)効率的です 。列がnull許容の場合、 NOT EXISTS
最も効率的です(ここでも、それほど多くはありません)。
Oracle
内 、3つのクエリすべてで同じプランが生成されます( ANTI JOIN
。
SQL Server
内 、 NOT IN
/存在しません
LEFT JOIN / IS NULL
であるため、より効率的です。 ANTI JOIN
に最適化することはできません オプティマイザによって。
PostgreSQL
で 、 LEFT JOIN / IS NULL
およびNOTEXISTS
NOT IN
よりも効率的です 、sineそれらは Anti Join
に最適化されています 、 NOT IN
ハッシュされたサブプラン
を使用します (または単純な<code>サブプラン サブクエリが大きすぎてハッシュできない場合)