Вы выбираете пользователей, у которых есть хотя бы один платёж. В таблице payments поле user_id иногда бывает NULL (например, анонимные платежи). Почему в такой ситуации часто предпочитают EXISTS, а не IN?

AIN и EXISTS всегда полностью эквивалентны при любых данных, поэтому выбор между ними не влияет на корректность результата
BЛучше IN, потому что он автоматически отбрасывает NULL в подзапросе и поэтому не зависит от пропусков в данных
CЛучше IN, потому что он возвращает TRUE, если в подзапросе есть хотя бы один NULL среди значений сравниваемого столбца
DЧасто выбирают EXISTS, потому что он проверяет факт существования строк и не зависит от NULL в значениях подзапроса
Правильный ответ. EXISTS отвечает на вопрос «есть ли подходящая строка», а IN сравнивает значения и может дать UNKNOWN, если список содержит NULL.

Разбор

Предикат x IN (subquery) использует трёхзначную логику: если прямого совпадения нет, но в наборе есть NULL, результат может стать UNKNOWN, и строка не пройдёт фильтр. EXISTS не сравнивает значения и потому не «ломается» из-за NULL: он просто проверяет, есть ли хотя бы одна строка, удовлетворяющая условиям корреляции. Утверждения про полную эквивалентность, автоматический отброс NULL или возврат TRUE от NULL неверно описывают семантику IN.

Можно заниматься бесплатно

Готовим вопросы…

Три вопроса по теме этой страницы, с объяснениями.

Продолжить в браузере

Ещё вопросы по теме «Подзапросы и CTE»