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