Я думаю, вы неправильно понимаете, как коррелированный подзапрос работает вместе с EXISTS
.
Равное сравнение (=
) оценивает конкретное значение против другого конкретного значения и возвращает true или false. Он не может оценить несколько значений, если вы не добавите дополнительные логические операторы AND
/ OR
. Оператор IN
- это просто способ упростить набор OR
с помощью операторов =
, поэтому его легче читать, как объяснил Зохар в другом ответе.
С другой стороны, оператор EXISTS
использует левое полусоединение для проверки существования конкретной записи. EXISTS
используется в логических контекстах всякий раз, когда вы хотите проверить, существует ли конкретная строка или нет. Механизм SQL прекращает поиск совпадающих строк , как только находит первую . Это цель левого полусоединения и одно из отличий с левым внешним объединением (кроме получения данных таблицы присоединения) и соответствующие суммы строк).
Итак, когда вы пишете:
FROM
sales.customers c
WHERE
EXISTS (
SELECT *
FROM sales.orders o
WHERE o.customer_id = c.customer_id
)
Вы используете коррелированную ссылку на подзапрос customers
с orders
. Подзапрос используется в контексте оператора EXISTS
, он будет выполнять поиск движка для каждой строки sales.customers
, если в sales.orders
есть строка не менее 1, удовлетворяющая этому условию :
WHERE o.customer_id = c.customer_id
Это условие будет отображаться как false
для каждого заказа, который не от клиента, которого мы в настоящее время проверяем. Двигатель будет игнорировать эти строки, потому что мы ищем существование. Будут возвращены только строки из customers
, имеющие customer_id
, который создает строку в подзапросе.
Если мы изменим условие на IN
:
FROM
sales.customers c
WHERE
EXISTS (
SELECT *
FROM sales.orders o
WHERE o.customer_id IN (c.customer_id)
)
Подзапрос проверит наличие в таблице sales.orders
, удовлетворяющее условию:
WHERE o.customer_id IN (c.customer_id)
Это тот же c.customer_id
, на который мы ссылались в примере =
. Поведение для двигателя будет таким же, как в предыдущем примере; проверьте, есть ли хотя бы одна строка в orders
, соответствующая customer_id
из customers
.
Следовательно, и =
, и IN
будут работать одинаково.