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

AНаписать INNER JOIN orders o ON o.user_id = u.id: соединение вернёт по строке на каждого пользователя
BНаписать WHERE u.id IN (SELECT DISTINCT user_id FROM orders): DISTINCT ускорит поиск по индексу
CНаписать INNER JOIN (SELECT user_id FROM orders LIMIT 1) o ON o.user_id = u.id: LIMIT исключит дубликаты
DНаписать WHERE EXISTS (SELECT 1 FROM orders o WHERE o.user_id = u.id): поиск остановится на первом совпадении
Правильный ответ. EXISTS проверяет наличие хотя бы одной строки и не дублирует результат, тогда как INNER JOIN создаст по строке на каждый заказ.

Разбор

EXISTS (подзапрос) — это полусоединение: для каждого пользователя проверяется, существует ли хотя бы одна строка в orders, и поиск прекращается при первом совпадении. Результат — ровно одна строка на пользователя. INNER JOIN без предварительной дедупликации orders создаст столько строк, сколько заказов у пользователя. IN тоже работает корректно, но DISTINCT внутри не «быстрее индекса».

Проверь себя · 1/3разбор после ответа
Нужно получить уникальный список идентификаторов пользователей из двух каналов: campaign_a(user_id) и campaign_b(user_id). Как корректнее объединить списки, чтобы убрать дубликаты?
Тренировать SQL в Telegram

Ещё вопросы по теме «JOIN и операции множеств»