Есть таблицы payments(user_id) и refunds(user_id). Нужно получить пользователей, у которых был платёж, но не было ни одного возврата. Какой запрос корректнее всего описывает задачу?

ASELECT user_id FROM payments INTERSECT SELECT user_id FROM refunds
BSELECT p.user_id FROM payments p INNER JOIN refunds r ON p.user_id = r.user_id
CSELECT user_id FROM payments EXCEPT SELECT user_id FROM refunds
DSELECT user_id FROM payments UNION ALL SELECT user_id FROM refunds
Правильный ответ. EXCEPT возвращает разность множеств: значения из первой выборки, которых нет во второй.

Разбор

Для условия «платили, но не возвращали» нужна именно разность наборов пользователей, и EXCEPT делает это напрямую на уровне множеств. INTERSECT и INNER JOIN дают пересечение — пользователей, у которых были и платежи, и возвраты, что прямо противоположно задаче. UNION ALL объединит обе таблицы и не отфильтрует возвраты. Альтернативой EXCEPT может быть LEFT JOIN ... WHERE r.user_id IS NULL или NOT IN, но именно EXCEPT короче всего описывает разность.

Можно заниматься бесплатно

Готовим вопросы…

Три вопроса по теме этой страницы, с объяснениями.

Продолжить в браузере

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