Вы выбираете пользователей, у которых есть хотя бы один платёж. В таблице 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.

Проверь себя · 1/3разбор после ответа
Вы считаете метрику: доля пользователей, которые совершили покупку в течение 7 дней после регистрации. Какой вариант построения запроса делает логику наиболее проверяемой и удобной для отладки?
Тренировать SQL в Telegram

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