Пытаясь найти решение этого вопроса - PullRequest
0 голосов
/ 04 октября 2019

Устранение дубликатов ответов и несоответствия в SQL

Итак, проблема состоит в том, что мне нужно найти транзакции, которые происходили каждый день, и существует несоответствие между моим ответом на правильный ответ, и я не знаю, почему!

Это краткое описание базы данных "Фирма по переработке отходов"

Фирма владеет несколькими центрами выкупа для сбора материалов, пригодных для переработки. Каждый из них получает средства, подлежащие выплате поставщикам вторсырья. Данные о полученных средствах записываются в таблицу Income_o (точка, дата, вкл.). Первичным ключом является (точка, дата), где точка содержит идентификатор центра выкупа, а дата соответствует календарной дате поступления средств. были получены. Столбец даты не включает временную часть, поэтому деньги (вкл.) Поступают не чаще одного раза в день для каждого центра. Информация о платежах поставщикам вторсырья хранится в таблице Outcome_o (точка, дата, выход). В этой таблице первичный ключ (точка, дата) гарантирует, что каждый центр выкупа сообщает о платежах (вне) не чаще одного раза в день. , слишком. В случае, если доходы и расходы могут возникать чаще, чем раз в день, используется другая схема базы данных с таблицами, имеющими первичный ключ, состоящий из кода из одного столбца: Доход (код, точка, дата, вкл.) Результат (код, точка, дата,out) Здесь столбец даты также не включает в себя временную часть.

и вопрос заключается в следующем: при условии, что денежные поступления (вкл.) и выплаты (выходные) могут быть зарегистрированы любое количество раздень для каждой точки сбора [т.е. столбец кода является первичным ключом], отобразите таблицу с одной соответствующей строкой для каждой рабочей даты каждой точки сбора. Набор результатов: точка, дата, общая выплата в день (вне), общее потребление денег в день (вкл.). Пропущенные значения считаются NULL.

SELECT Income.point, Income."date", SUM("out"), SUM(inc)
FROM Income left JOIN 
 Outcome ON Income.point = Outcome.point AND
 Income."date" = Outcome."date" 

GROUP BY Income.point, Income."date"
UNION 
SELECT Outcome.point, Outcome."date", SUM("out"), SUM(inc)
FROM Outcome left JOIN 
 Income ON Income.point = Outcome.point AND
 Income."date" = Outcome."date" 

GROUP BY Outcome.point, Outcome."date";

1 Ответ

0 голосов
/ 04 октября 2019

Я предполагаю, что у вас есть некоторая декартова связь, если вы не включили CODE в свои критерии соединения. Я думаю, что следующий запрос должен удовлетворить ваши потребности:

WITH calendar AS
(
  SELECT TRUNC(SYSDATE)-(LEVEL-1) AS DT
  FROM DUAL
  CONNECT BY LEVEL < 30
)
SELECT d.pnt AS "POINT",
       c.dt AS "DATE",
       d.outcome_total,
       d.income_total
FROM calendar c
LEFT JOIN (SELECT nvl(inc.pnt, outc.pnt) AS PNT,
                  nvl(inc.dt, outc.dt) AS DT,
                  outc.amt AS OUTCOME_TOTAL,
                  inc.amt AS INCOME_TOTAL
           FROM (SELECT i.pnt, i.dt, sum(i.inc) AS AMT
                 FROM income i
                 GROUP BY i.pnt, i.dt) inc
           FULL JOIN (SELECT o.pnt, o.dt, sum(o.inc) AS AMT
                      FROM outcome o
                      GROUP BY o.pnt, o.dt) outc ON inc.pnt = outc.pnt AND inc.dt = outc.dt) d ON c.dt = d.dt;

Я добавил таблицу календаря, чтобы учесть случай, когда не было ни дохода, ни результата в данный день. Однако, если вам это не нужно, запрос в пределах LEFT JOIN должен быть в порядке.

Примечание: с добавлением предложения WITH в календаре этот запрос покажет только результаты за последний месяц (-ish). Если вам нужно больше времени, настройте 30-дневное окно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...