Нужно вывести по каждому заказу признак has_refund: есть ли хотя бы одна запись в refunds по этому заказу. Таблица refunds может иметь несколько строк на один заказ. Какой вариант корректен и не размножает заказы?

ASELECT o.order_id, r.refund_id IS NOT NULL AS has_refund FROM orders o LEFT JOIN refunds r ON r.order_id = o.order_id
BSELECT o.order_id, (SELECT r.refund_id FROM refunds r WHERE r.order_id = o.order_id) AS has_refund FROM orders o
CSELECT o.order_id, CASE WHEN EXISTS (SELECT 1 FROM refunds r WHERE r.order_id = o.order_id) THEN 1 ELSE 0 END AS has_refund FROM orders o
DSELECT o.order_id FROM orders o WHERE o.order_id IN (SELECT r.order_id FROM refunds r) AND 1 AS has_refund
Правильный ответ. EXISTS внутри CASE даёт один логический ответ на строку orders и не создаёт дубликаты строк.

Разбор

LEFT JOIN к таблице refunds может размножить строки заказов, если по заказу несколько возвратов. Скалярный подзапрос, который возвращает refund_id, тоже рискован: при нескольких строках он упадёт. Конструкция CASE WHEN EXISTS (...) THEN 1 ELSE 0 END явно выражает проверку наличия связанных строк и всегда возвращает одно значение на заказ.

Проверь себя · 1/3разбор после ответа
Нужно посчитать средний дневной доход: сначала SUM(amount) по каждому дню, затем AVG по дням. Какой запрос соответствует этой логике?
Тренировать SQL в Telegram

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