Вы хотели посчитать средний чек по заказам как AVG(order_total). Но перед этим соединили orders с order_items по order_id (связь один-ко-многим). Почему AVG() может измениться по сравнению с расчётом на таблице orders?
AПосле соединения
AVG() пересчитывается по новой формуле и игнорирует строки, у которых order_total совпадает с уже учтёнными заказамиBПосле соединения связь становится один-к-одному, поэтому каждый
order_total учитывается ровно один раз и среднее всегда оказывается выше прежнегоCПосле соединения каждый
order_total повторился по числу строк в order_items, и AVG() стал взвешен по числу позиций в заказеDПосле соединения
DISTINCT автоматически убирает крупные order_total и оставляет только типичные суммы, поэтому среднее заметно меняетсяПравильный ответ. После соединения один-ко-многим
AVG() по полю заказа становится взвешенным из-за дублирования строк.Разбор
В исходной таблице orders один заказ равен одной строке, поэтому AVG(order_total) — простой средний чек по заказам. После соединения с order_items каждый заказ повторяется столько раз, сколько у него позиций, и влияет на среднее несколько раз. Чтобы избежать искажения, считайте AVG() на уровне заказа или предварительно агрегируйте order_items до order_id перед соединением.
Проверь себя · 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`. В обеих таблицах по пользователю много строк (один-ко-многим). Какой подход минимизирует риск размножения строк в соединении?
- В каком случае `SUM(order_amount)` после `JOIN` скорее всего останется корректным, без эффекта размножения строк?
- Все вопросы по «JOIN и кардинальность» →