Вы соединили таблицы users и orders (один ко многим) и посчитали AVG(order_amount), интерпретируя это как «средняя выручка на пользователя». Почему это неверно и как правильно?
AНеверно, потому что
AVG() считает только по целым числам и пропускает дробные суммы; правильно использовать SUM() и затем поделить на пользователейBВерно:
AVG(order_amount) всегда равно средней выручке на пользователя при условии, что у каждого пользователя есть хотя бы один заказ в выборкеCНеверно, потому что
INNER JOIN удаляет пользователей без заказов; нужно LEFT JOIN и тогда средняя выручка на пользователя посчитается корректно из коробкиDНеверно, потому что
AVG() считает среднее по строкам заказов, а не по пользователям; нужно сначала агрегировать выручку до user_id через SUM(), а затем взять AVG() по пользователямПравильный ответ. При связи один ко многим
AVG() по полю заказа даёт среднее по заказам, а не по пользователям, из-за разной мощности связи между таблицами.Разбор
Пользователь с десятью заказами будет весить в среднем в десять раз больше пользователя с одним заказом, поэтому получается среднее по строкам заказов. Если цель — метрика на пользователя, сначала посчитайте выручку на user_id через SUM() по заказам, а уже потом усредняйте. Это базовое правило выбора уровня агрегации перед JOIN и после него. Версии с LEFT 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 и кардинальность» →