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

Проверь себя · 1/3разбор после ответа
В одном отчёте вы считаете несколько метрик по событиям: dau, wau и число покупок. У всех метрик один и тот же фильтр: только продакшн-трафик и только выбранный период. Какой подход лучше защищает от ситуации, когда в одной метрике забыли часть фильтра?
Тренировать SQL в Telegram

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