Почему дублируются значения при джоине 2х таблиц?

Здравствуйте. Есть 3 таблицы: b_sale_order, d_sale_order_prepayment, d_sale_order_excess_fare. Таблица с заказами имеет связь 1 ко многим с остальными. В таблице d_sale_order_prepayment 1 запись, в таблице d_sale_order_excess_fare 2 записи. Я написал запрос, в котором собираю эти 3 таблицы. Проблема в том, что запись для d_sale_order_prepayment дублируется. Запрос:

SELECT O.ID, OP.VALUE AS PREPAYMENT, EF.VALUE AS PAYMENT
FROM b_sale_order O
LEFT JOIN  `d_sale_order_prepayment` OP ON ( OP.order_id = O.ID ) 
LEFT JOIN  `d_sale_order_excess_fare` EF ON ( EF.order_id = O.ID )


f11ba5ec00aa407cb41e34d60c3027c3.png
Данные:
ec40a80b3766402bbe54bab4c7bb618a.png434c605b5b8849948bf75902c40d76f4.png
  • Вопрос задан
  • 987 просмотров
Решения вопроса 1
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Если надо получать суммы, то проще всего делать JOIN сразу с суммами.
SELECT `o`.`ID`, IFNULL(`op`.`VALUE`, 0) AS `prepayment`, IFNULL(`ef`.`VALUE`, 0) AS `payment`
    FROM `b_sale_order` AS `o`
    LEFT JOIN  (
        SELECT `order_id`, SUM(`VALUE`) AS `VALUE`
            FROM `d_sale_order_prepayment` 
            GROUP BY `order_id`
    ) AS `op` ON `op`.`order_id` = `o`.`ID`
    LEFT JOIN  (
        SELECT `order_id`, SUM(`VALUE`) AS `VALUE`
            FROM `d_sale_order_excess_fare` 
            GROUP BY `order_id`
    ) AS `ef` ON `ef`.`order_id` = `o`.`ID`
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
@dmitryKovalskiy
программист средней руки
На первый взгляд все корректно. А вам как надо?
Ответ написан
@pihel
Sql, Oracle, pl/sql, BI, ETL, php, olap
Если prepayment один, то можно его взять максом:
SELECT O.ID, MAX(OP.VALUE) AS PREPAYMENT, SUM(EF.VALUE) AS PAYMENT
FROM b_sale_order O
LEFT JOIN  `d_sale_order_prepayment` OP ON ( OP.order_id = O.ID ) 
LEFT JOIN  `d_sale_order_excess_fare` EF ON ( EF.order_id = O.ID )
GROUP BY O.ID


Если же в обоих таблицах может быть более 1 записи, а не только в d_sale_order_excess_far, то или бить запрос на 2 или попробовать использовать аналитические функции:
SELECT O.ID,
SUM(OP.VALUE) OVER (PARTITION BY O.ID ) AS PREPAYMENT,
SUM(EF.VALUE) OVER (PARTITION BY O.ID ) AS PREPAYMENT AS PAYMENT
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы