Вы соединили users и orders (one-to-many) и посчитали AVG(order_amount), интерпретируя это как «средняя выручка на пользователя». Почему это неверно и как правильно?
AНеверно, потому что
AVG() считает только целые числа; правильно использовать SUM()BВерно:
AVG(order_amount) всегда равно выручке на пользователяCНеверно, потому что
INNER JOIN удаляет пользователей; нужно LEFT JOIN и тогда всё станет правильноDНеверно, потому что
AVG() считает среднее по заказам, а не по пользователям; нужно сначала pre-aggregate выручку до user_id, а затем взять AVG() по пользователямПравильный ответ. В
one-to-many JOIN AVG() по полю заказа даёт среднее по заказам, а не по пользователям из-за разного cardinality.Разбор
Пользователь с 10 заказами будет «весить» в среднем в 10 раз больше пользователя с одним заказом, поэтому получается среднее по строкам заказов. Если цель — метрика на пользователя, сначала посчитайте выручку на user_id через SUM() по заказам, а уже потом усредняйте. Это базовое правило выбора уровня агрегации перед и после JOIN.
Проверь себя · 1/3разбор после ответа
В
events(user_id, event_id) у пользователя может быть много строк, и в orders(user_id, order_id) тоже много строк. Вы соединяете их по user_id. Какая cardinality получается на ключе и как это влияет на строки?Ещё вопросы по теме «JOIN и кардинальность»
- В таблице `users` 100 000 строк, в таблице `user_profiles` — ровно одна строка на каждого `user_id`. Вы делаете `INNER JOIN` по `user_id`. Что верно про число строк результата?
- Вы соединяете `users` и `orders` по `user_id`, где у пользователя может быть много заказов (`one-to-many`). Как посчитать число пользователей, которые сделали хотя бы один заказ, чтобы избежать `duplication`?
- Для одного `order_id` в `order_items` есть 3 строки, а в `payments` есть 2 строки. Вы соединили всё в одну таблицу по `order_id` без предварительной агрегации. Сколько строк получится для этого заказа и почему?
- Нужен датасет на уровне `user_id`: выручка из `orders` и число сессий из `sessions`. В обеих таблицах по пользователю много строк (`one-to-many`). Какой подход минимизирует риск `join explosion`?
- Вы хотели посчитать средний чек по заказам как `AVG(order_total)`. Но перед этим соединили `orders` с `order_items` по `order_id` (`one-to-many`). Почему `AVG()` может измениться по сравнению с расчётом на таблице `orders`?
- Все вопросы по «JOIN и кардинальность» →