В payments(order_id, amount, status) для одного order_id может быть несколько попыток оплаты (one-to-many), например повторные списания или ошибки. Вы хотите посчитать выручку по заказам из orders. Что наиболее безопасно сделать перед соединением, чтобы SUM() не завысилась из-за duplication?
AСоединить как есть и потом применить
distinct ко всем строкамBСначала
pre-aggregate payments до одной строки на order_id, затем соединить с ordersCСоединить
payments с orders по user_id, так будет больше совпаденийDЗаменить
SUM() на COUNT(*)Правильный ответ. При
one-to-many по order_id деньги нужно сводить до одного факта на заказ через pre-aggregate, иначе появится duplication в SUM().Разбор
Если у заказа несколько платежных строк, то orders начнёт дублироваться при JOIN, и каждая попытка попадёт в расчёт. В зависимости от бизнес-логики нужно выбрать правило: только успешные платежи, последний успешный или сумма успешных. После pre-aggregate соединение становится ближе к one-to-one, и денежные метрики становятся интерпретируемыми.
Проверь себя · 1/3разбор после ответа
В
orders 120 строк (по одной на order_id). В order_items ровно по 3 строки на каждый order_id. Сколько строк будет после соединения orders → order_items по order_id и почему?Ещё вопросы по теме «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 и кардинальность» →