У пользователя может быть несколько заказов в orders и несколько возвратов в refunds. Вы соединили orders и refunds по user_id и посчитали SUM(refund_amount). Что наиболее вероятно произойдёт с суммой и почему?
AСумма не изменится, потому что
SUM() устойчив к повторам строк и сам убирает дублирование значений по ключу user_id.BСумма станет меньше, потому что
INNER JOIN удалит часть возвратов у пользователей, у которых на одного пользователя приходится несколько заказов.CСумма завысится: получится связь «многие ко многим» по
user_id, и каждый возврат повторится для каждого заказа этого пользователя.DСумма станет равна числу пользователей, потому что
COUNT(*) и SUM() после JOIN по user_id дают эквивалентный результат.Правильный ответ. Когда обе стороны имеют несколько строк на
user_id, JOIN становится «многие ко многим» и раздувает SUM() из-за повторов.Разбор
Внутри одного пользователя заказы и возвраты комбинируются, образуя пары «каждый с каждым». В результате один и тот же возврат попадает в несколько строк и учитывается несколько раз в SUM(refund_amount). Чтобы исправить, нужно предварительно агрегировать одну из сторон до user_id либо соединять по более точному ключу, например order_id. Это классическая ошибка раздувания при JOIN по неполному ключу.
Проверь себя · 1/3разбор после ответа
Вы соединяете таблицы пользователей и заказов по
user_id, где у одного пользователя может быть много заказов (связь «один ко многим»). Как посчитать число пользователей, которые сделали хотя бы один заказ, и не получить дубли?Ещё вопросы по теме «JOIN и кардинальность»
- В таблице `users` 100 000 строк, в таблице `user_profiles` — ровно одна строка на каждого `user_id`. Вы делаете `INNER JOIN` по `user_id`. Что верно про число строк результата?
- Вы соединяете таблицы пользователей и заказов по `user_id`, где у одного пользователя может быть много заказов (связь «один ко многим»). Как посчитать число пользователей, которые сделали хотя бы один заказ, и не получить дубли?
- Для одного `order_id` в `order_items` есть 3 строки, а в `payments` — 2 строки. Вы соединили обе таблицы по `order_id` без предварительной агрегации. Сколько строк получится для этого заказа и почему?
- Нужен набор данных на уровне `user_id`: выручка из `orders` и число сессий из `sessions`. В обеих таблицах по пользователю много строк (один-ко-многим). Какой подход минимизирует риск размножения строк в соединении?
- Вы хотели посчитать средний чек по заказам как `AVG(order_total)`. Но перед этим соединили `orders` с `order_items` по `order_id` (связь один-ко-многим). Почему `AVG()` может измениться по сравнению с расчётом на таблице `orders`?
- Все вопросы по «JOIN и кардинальность» →