试图找出解决这个问题的方法

时间:2019-10-04 14:27:33

标签: sql oracle

消除重复的答案和SQL中的不匹配

因此问题表明,我需要查找每天发生的交易,正确答案的答案与我不知道的原因不匹配!

这是简短的数据库描述“回收公司”

该公司拥有几个回购中心,以收集可回收材料。他们每个人都收到要支付给可回收物品供应商的资金。表中记录了收到的资金数据 Income_o(点,日期,公司) 主键是(点,日期),其中该点包含回购中心的标识符,并且该日期对应于收到资金的日历日期。日期栏不包含时间部分,因此每个中心每天最多只能收到一次钱(inc)。表中包含有关向可回收材料供应商付款的信息 结果_o(点,日期,输出) 在此表中,主键(点,日期)确保每个回购中心每天也最多报告一次有关付款(支出)的报告。 对于一天可能发生多次收入和支出的情况,使用另一个数据库模式,该数据库模式的表的主键由单列代码组成: 收入(代码,点,日期,公司) 结果(代码,点,日期,结果) 这里,日期列也不包含时间部分。

,问题是: 在这样的假设下,每个收款点每天可以注册任意次数的收款(inc)和付款(out)[即[代码列是主键],则显示一个表,其中每个收集点的每个操作日期都有一个对应的行。 结果集:点,日期,每天总支出(支出),每天总货币摄入量(inc)。 缺少的值被认为是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 :(得分:0)

我的猜测是,由于不包含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中的查询应该很好。

N.B .:添加日历WITH子句后,此查询当前仅显示上个月(-ish)的结果。如果需要更长的时间,请调整30天窗口。