В events(user_id, event_id) у пользователя может быть много строк, и в orders(user_id, order_id) тоже много строк. Вы соединяете их по user_id. Какая связь получается на ключе и как это влияет на строки?
AЭто
many-to-many: строки по каждому user_id перемножаются, и возможен взрывной рост числа строк после соединенияBЭто
one-to-one: по каждому user_id после соединения будет ровно одна строка, как при соединении уникальных ключейCЭто
one-to-many: общее число строк после соединения станет равно числу уникальных пользователей в обеих таблицахDЭто
one-to-one, если перед соединением применить DISTINCT к каждой из таблиц по полю user_idПравильный ответ. Два источника, где по ключу много строк, при
JOIN дают many-to-many и риск взрывного роста числа строк.Разбор
Если у пользователя 5 событий и 2 заказа, после JOIN получится 10 строк только для него — это и есть размножение строк, которое ломает COUNT(*), SUM() и даже AVG() при неверном уровне анализа. Чтобы избежать, выбирают правильный ключ соединения или делают предварительную агрегацию до нужной гранулярности. Варианты one-to-one и one-to-many неверно описывают ситуацию: при многих строках с обеих сторон связь по ключу всегда many-to-many. DISTINCT по user_id теряет данные, а не превращает соединение в one-to-one.
Проверь себя · 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 и кардинальность» →