Нужно выбрать заказы только тех пользователей, у которых был логин после :cutoff_date. Какой вариант корректен?

ASELECT * FROM orders o WHERE EXISTS (SELECT 1 FROM events e WHERE e.event_name = 'login' AND e.event_time >= :cutoff_date)
BSELECT * FROM orders o WHERE EXISTS (SELECT 1 FROM events e WHERE e.user_id = o.user_id AND e.event_name = 'login' AND e.event_time >= :cutoff_date)
CSELECT * FROM orders o WHERE o.user_id = (SELECT e.user_id FROM events e WHERE e.event_name = 'login' AND e.event_time >= :cutoff_date)
DSELECT * FROM orders o WHERE o.user_id IN (SELECT COUNT(*) FROM events e WHERE e.event_name = 'login' AND e.event_time >= :cutoff_date)
Правильный ответ. Чтобы проверить активность именно текущего пользователя, подзапрос должен быть коррелирован по user_id.

Разбор

В некоррелированном варианте EXISTS отвечает на вопрос «был ли вообще хоть один логин после даты» и, если да, пропустит все заказы. Корреляция e.user_id = o.user_id делает проверку персональной для каждой строки заказа. Ошибка с = вместо IN/EXISTS часто приводит к ситуации, когда подзапрос возвращает много строк и запрос падает.

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

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