ВЫБЕРИТЕ с помощью LEFT JOIN, выполняющего математическую операцию дважды? - PullRequest
0 голосов
/ 10 декабря 2018

Общая идея того, что я пытаюсь сделать, заключается в следующем: выберите все плановые цены для заказа, затем вычтите из этой суммы все фактические цены по этому заказу.

Плановая цена и фактическая ценана разных столах.Когда у меня есть единая плановая цена и единственная фактическая цена, это прекрасно работает.Однако, когда у меня есть несколько плановых цен или несколько фактических цен, это дает мне странные результаты, как будто алгебра повторяется несколько раз.

Запрос:

    SELECT PL.orderid, (SUM(PL.lineprice) - NVL(SUM(AC.lineprice),0)) AS 
    Difference FROM plans PL
    LEFT JOIN actuals AC ON PL.orderid = AC.orderid
    WHERE PL.customer IN (SELECT customer FROM ...)
    GROUP BY PL.orderid
    ORDER BY PL.orderid;

Результаты запроса:

Orderid Difference
X-1224      100
X-1226      80
X-1345      70000
X-1351      125000
X-1352      10000
Y-2403      190000

Моя таблица планов выглядит следующим образом:

Orderid Planned_Price
X-1224      100
X-1226      100
X-1345      105000
X-1351      100000
X-1352      10000
X-1352      50000
Y-2403      25000
Y-2403      100000

А моя фактическая таблица выглядит так:

Orderid Actual_Price
X-1226      20
X-1345      35000
X-1351      25000
X-1351      50000
X-1352      25000
Y-2403      25000
Y-2403      5000

Так что, похоже, работает, когда у меня есть толькоодна строка в каждой таблице или одна строка в планах и нет строк в фактических значениях , т. е. X-1224, X-1226 и X-1345 .

Однако результаты слишком высоки илислишком низко, когда у меня есть несколько строк с одинаковым OrderID в любой таблице , т. е. все остальные

Я в тупике, почему это так.Любые идеи приветствуются.

редактировать: Я хотел бы получить результаты, взяв в качестве примера Y-2403: (25000 + 100000) - (25000 + 5000) = 95000. Что яполучить вдвое больше, чем в 190000 году.

Ответы [ 2 ]

0 голосов
/ 10 декабря 2018

Полагаю, вы хотите сравнить summed_up_prices по идентификатору заказа в таблице плана с ценами summed_up по идентификатору заказа в таблице фактического плана.по заказу

select a.orderid
       ,NVL(max(b.summed_up),0) - sum(a.actual_price) as difference          
     from actual_table a
left join (select pt.orderid
                 ,sum(pt.planned_price) as summed_up
            from planned_table pt
           group by pt.orderid
           )b
        on a.orderid=b.orderid
  group by a.orderid

+---------+------------+
| ORDERID | DIFFERENCE |
+---------+------------+
| X-1226  |         80 |
| Y-2403  |      95000 |
| X-1351  |      25000 |
| X-1345  |      70000 |
| X-1352  |      35000 |
+---------+------------+

Вот ссылка dbfiddle с данными

https://dbfiddle.uk/?rdbms=oracle_11.2&fiddle=3cacffd19b39ecaf7ad752dff262ac47

0 голосов
/ 10 декабря 2018

Почему это так?

Потому что так работает join.Если у вас есть такие данные:

 a
 1
 1
 2
 2

И b:

 b
 1
 1
 1
 2

, то результат join с 6 "1" с и 2 "2" с.

Ваш вопрос не говорит о том, что вы хотите для результатов, но типичным подходом является агрегирование до выполнения объединений.

РЕДАКТИРОВАТЬ:

Вы, кажется, хотите:

select p.orderid,
       (p.lineprice - coalesce(lineprice, 0)) as Difference
from (select orderid, sum(lineprice) as lineprice
      from plans p
      group by orderid
     ) p left join
    (select orderid, sum(lineprice) as lineprice
     from actuals a
     group by orderid
    ) a
    on p.orderid = a.orderid
where p.customer in (SELECT customer FROM ...)
order by p.orderid;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...