WHERE NOT EXISTS (...)
で始まるサブクエリではなく、LEFT OUTER JOIN
を使用することの違いは何ですか?
いいえ、それらはnotが最も単純なユースケースで同じ行セットを返すため、同じものではありません。
_LEFT OUTER JOIN
_は、行が関連テーブルに存在する場合と存在しない場合の両方で、左側のテーブルからすべての行を返します。 WHERE NOT EXISTS()
サブクエリは、関係が満たされていない行のみを返します。
ただし、_LEFT OUTER JOIN
_を実行し、WHERE
句の外部キー列で_IS NULL
_を検索した場合、_WHERE NOT EXISTS
_と同等の動作を行うことができます。
_SELECT
t_main.*
FROM
t_main
LEFT OUTER JOIN t_related ON t_main.id = t_related.id
/* IS NULL in the WHERE clause */
WHERE t_related.id IS NULL
_
_SELECT
t_main.*
FROM t_main
WHERE
NOT EXISTS (
SELECT t_related.id
FROM t_related
WHERE t_main.id = t_related.id
)
_
_t_main
_に関連する行がある場合とない場合の両方で、_t_related
_から行を返します。
_SELECT
t_main.*
FROM
t_main
LEFT OUTER JOIN t_related ON t_main.id = t_related.id
/* WHERE clause does not exclude NULL foreign keys */
_
注これは、クエリのコンパイル方法と実行方法については触れていません。これも異なります。これは、クエリが返す行セットの比較に対処するだけです。
マイケルはすでにあなたの質問に答えたので、違いを説明するための簡単なサンプルです:
Table A
Key Data
1 somedata1
2 somedata2
Table B
Key Data
1 data1
左外部結合:
SELECT *
FROM A
LEFT OUTER JOIN B
ON A.Key = B.Key
結果:
Key Data Key Data
1 somedata1 1
2 somedata2 null null
EXISTSの使用:
SELECT *
FROM A WHERE EXISTS ( SELECT B.Key FROM B WHERE A.Key = B.Key )
存在しない:
SELECT *
FROM A WHERE NOT EXISTS ( SELECT B.Key FROM B WHERE A.Key = B.Key )
結果:
Key Data
2 somedata2
左外部結合は、存在しない場所よりも柔軟性があります。子テーブルから列を返す場合は、左外部結合を使用する必要があります。左外部結合を使用して、親テーブルに一致するレコードと、一致しない親テーブル内のすべてのレコードを返すこともできます。存在しない場所では、一致しないレコードのみを返すことができます。
ただし、それらが同等の行を返し、正しいテーブルに列が必要ない場合は、存在する場所がよりパフォーマンスの高い選択肢である可能性があります(少なくともSQLサーバーでは、他の場所については知りませんdbs)。
私は、OPが(機能的にが同じである場合にどの構成がより良いかを知りたいと思っていたと思います(つまり、セカンダリテーブルに一致がない行のみを表示したい)。
そのため、WHERE NOT EXISTSは常に同じくらい速くなるので、慣れるのが良い習慣です。
結局のところ、答えはSQLでリレーショナル演算antijoin
を実行するために両方が(他の構成体の中で)使用されていると思います。