Нет, это не одно и то же, поскольку они не возвращают один и тот же набор строк в наиболее упрощенном случае.
LEFT OUTER JOIN
вернет все строки из левой таблицы, где есть строки в связанной таблице, а где нет. Подзапрос WHERE NOT EXISTS()
будет возвращать только те строки, в которых отношение не встречается.
Однако, если вы выполнили LEFT OUTER JOIN
и искали IS NULL
в столбце внешнего ключа в предложении WHERE
, вы можете сделать поведение, эквивалентное 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 */
Примечание Это не говорит о том, как запросы компилируются и выполняются, что также отличается - это касается только сравнения наборов строк, которые они возвращают.