Вы выбираете пользователей, у которых есть хотя бы один платеж. В таблице payments поле user_id иногда бывает NULL (например, анонимные платежи). Почему в такой ситуации часто предпочитают EXISTS, а не IN?
A
IN и 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 и число покупок. У всех метрик один и тот же фильтр: только продакшн-трафик и только выбранный период. Какой подход лучше защищает от ситуации, когда в одной метрике забыли часть фильтра?Ещё вопросы по теме «Подзапросы и CTE»
- В отчёте нужно посчитать выручку по странам пользователей только по оплаченным заказам за период. Какой подход обычно делает запрос более читаемым и позволяет переиспользовать шаг фильтрации?
- Вы пишете `SELECT u.user_id, (SELECT order_id FROM orders o WHERE o.user_id = u.user_id) AS last_order_id FROM users u`. Что может пойти не так и как исправить, чтобы подзапрос стал скалярным?
- Нужно выбрать заказы, у которых `amount` выше среднего `amount` по тому же пользователю. Какой вариант `WHERE` корректно использует коррелированный подзапрос?
- Вы готовите дашборд: нужно (1) топ товаров по выручке за период и (2) общая выручка за тот же период. Какой вариант снижает риск, что фильтр по периоду рассинхронизируется между расчётами?
- Вы ищете пользователей без заказов. Почему запрос `SELECT u.user_id FROM users u WHERE u.user_id NOT IN (SELECT o.user_id FROM orders o)` может вернуть 0 строк и какой подход безопаснее?
- Все вопросы по «Подзапросы и CTE» →