Нужно найти пользователей, у которых был хотя бы один заказ и при этом нет ни одного заказа со статусом 'canceled'. Какой вариант корректно выражает это условие?

ASELECT u.user_id FROM users u WHERE u.user_id NOT IN (SELECT o.user_id FROM orders o WHERE o.status = 'canceled')
BSELECT u.user_id FROM users u LEFT JOIN orders o ON o.user_id = u.user_id GROUP BY u.user_id HAVING SUM(CASE WHEN o.status = 'canceled' THEN 1 ELSE 0 END) = 0
CSELECT u.user_id FROM users u WHERE EXISTS (SELECT 1 FROM orders o WHERE o.status <> 'canceled')
DSELECT u.user_id FROM users u WHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.user_id) AND NOT EXISTS (SELECT 1 FROM orders o2 WHERE o2.user_id = u.user_id AND o2.status = 'canceled')
Правильный ответ. Комбинация EXISTS + NOT EXISTS позволяет явно задать «есть хотя бы одна строка» и «нет ни одной строки с условием» для одного пользователя.

Разбор

Важно разделить две части бизнес-логики: (1) у пользователя должен быть хотя бы один заказ и (2) среди его заказов не должно быть отменённых. NOT IN может неожиданно вести себя при NULL, а вариант с LEFT JOIN часто включает пользователей без заказов (они проходят условие суммы). Пара EXISTS и NOT EXISTS делает оба требования явными и читабельными.

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

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