Вы соединили заказы с order_items и payments по order_id, а потом посчитали SUM(paid_amount). Сумма оказалась завышенной. Что вероятнее всего произошло и как исправить?
AИспользуется
INNER JOIN; заменить его на LEFT JOIN, тогда платежи перестанут дублироваться при соединении трёх таблицBСтроки умножились из-за нескольких записей в
order_items и payments; агрегировать каждую до уровня order_id и затем делать JOINCДело в
NULL в столбце paid_amount; обернуть сумму в COALESCE и заменить пустые значения на ноль для устранения завышенияDЗаменить
JOIN на UNION между подзапросами и оставить ключ заказа, тогда повторяющиеся платежи уйдут автоматическиПравильный ответ. При соединении нескольких таблиц с отношением «один-ко-многим» по одному ключу строки могут размножаться и завышать суммы.
Разбор
Если у заказа три позиции в order_items и два платежа в payments, после соединения получится шесть строк на один заказ. Тогда SUM(paid_amount) посчитает один и тот же платёж несколько раз. Типичный фикс — сначала агрегировать order_items до одной строки на order_id и отдельно агрегировать payments до одной строки на order_id, и только затем соединять эти агрегаты с заказами. Замена типа соединения или COALESCE проблему не решают.
Проверь себя · 1/3разбор после ответа
Как переписать запрос без
RIGHT JOIN, используя только LEFT JOIN? Исходный запрос: SELECT u.user_id, o.order_id FROM users u RIGHT JOIN orders o ON u.user_id = o.user_id;Ещё вопросы по теме «JOIN и операции множеств»
- В отчёте нужно вывести всех пользователей и количество их заказов, включая тех, у кого заказов нет. Какой тип соединения между `users` и `orders` по `user_id` нужен?
- Нужно посчитать число пользователей, которые сделали хотя бы 1 заказ (таблицы `users(user_id)` и `orders(user_id, order_id)`). Какой запрос посчитает правильно?
- Есть две таблицы с одинаковой схемой: `events_web(user_id, event_name, created_at)` и `events_app(user_id, event_name, created_at)`. Нужно получить общий поток событий для дальнейшей агрегации. Что использовать?
- Нужно получить уникальный список идентификаторов пользователей из двух каналов: `campaign_a(user_id)` и `campaign_b(user_id)`. Как корректнее объединить списки, чтобы убрать дубликаты?
- Как переписать запрос без `RIGHT JOIN`, используя только `LEFT JOIN`? Исходный запрос: `SELECT u.user_id, o.order_id FROM users u RIGHT JOIN orders o ON u.user_id = o.user_id;`
- Все вопросы по «JOIN и операции множеств» →