【问题标题】:Left Join not returning the missing information - SQL OracleLeft Join 不返回丢失的信息 - SQL Oracle
【发布时间】:2019-04-05 08:26:58
【问题描述】:

一个用于现金,另一个用于stage,结构如下

现金

FileID     Cash   Date
1           50   03.04.2017
2           100  08.07.2015
3           70   14.09.2018

舞台

FileID      Stage           Date_of_stage
1           Finished       06.04.2016
1           In Process     08.07.2015
2           Complication   17.08.2018
2           In Process     14.03.2018

虽然我的表有更多行。所以我加入了这两张桌子,因为我想使用这个选择按阶段对现金进行分组:

select fileID,  date, cash, max(date_of_stage) as max_date
from (select c.fileID, c.date, c.cash, s.stage, s.date_of_stage  
      from cash c
      inner join stage s
      on c.fileID=s.fileID
      and s.date_of_stage < c.date
      ) x
group by fileID, date, cash 

我只需要 max(date_of_stage) 因为它对我们的报告具有逻辑意义,而且这不是问题的一部分。

问题是:当我比较 cash 表和上述选择的总现金时,我从上述选择中得到的总金额比 cash 少一点表(来自 cash 的 700 万和来自上述选择的 690 万)。现在我正在尝试使用左连接来识别丢失的记录:

select *
from (select fileID, date, cash
  from cash) x

left join 

(select fileID,  date, cash, max(date_of_stage) as max_date
from (select c.fileID, c.date, c.cash, s.stage, s.date_of_stage  
      from cash c
      inner join stage s
      on c.fileID=s.fileID
      and s.date_of_stage < c.date
      ) 
group by fileID, date, cash ) y
on x.fileID=y.fileID
and x.date=y.date
and x.cash=y.cash
where y.fileID is null

但是这个左连接没有给出任何东西,所以我无法识别和检查丢失的记录。有什么提示该怎么做?

【问题讨论】:

  • 请在代码问题中给出minimal reproducible example--剪切&粘贴&可运行代码加上所需的输出加上清晰的规范和解释。最小意味着将最少的问题代码添加到最少的工作代码中。因此,给出您所展示的最少代码可以满足您的期望,并且在您出错的第一个地方提供最少的代码。 (调试基础。)

标签: sql oracle left-join


【解决方案1】:

通过改变左表尝试如下

 select x.*

 (select fileID,  date, cash, max(date_of_stage) as max_date
    from (select c.fileID, c.date, c.cash, s.stage, s.date_of_stage  
          from cash c
          inner join stage s
          on c.fileID=s.fileID
          and s.date_of_stage < c.date
          ) 
    group by fileID, date, cash ) x left join 

     (select fileID, date, cash
      from cash) y    


    on x.fileID=y.fileID
    and x.date=y.date
    and x.cash=y.cash
    where y.fileID is null

【讨论】:

    【解决方案2】:

    我认为您只需要在原始查询中进行左外连接,而不是内连接,例如:

    WITH cash AS (SELECT 1 fileid, 50 cash, to_date('03/04/2017', 'dd/mm/yyyy') dt FROM dual UNION ALL
                  SELECT 2 fileid, 100 cash, to_date('08/07/2015', 'dd/mm/yyyy') dt FROM dual UNION ALL
                  SELECT 3 fileid, 70 cash, to_date('14/09/2018', 'dd/mm/yyyy') dt FROM dual),
        stage AS (SELECT 1 fileid, 'Finished' stage, to_date('06/04/2016', 'dd/mm/yyyy') date_of_stage FROM dual UNION ALL
                  SELECT 1 fileid, 'In Process' stage, to_date('08/07/2015', 'dd/mm/yyyy') date_of_stage FROM dual UNION ALL
                  SELECT 2 fileid, 'Complication' stage, to_date('17/08/2018', 'dd/mm/yyyy') date_of_stage FROM dual UNION ALL
                  SELECT 2 fileid, 'In Process' stage, to_date('14/03/2018', 'dd/mm/yyyy') date_of_stage FROM dual)
    SELECT c.fileid,
           c.dt,
           c.cash,
           MAX(s.date_of_stage) max_date
    FROM   cash c
           LEFT OUTER JOIN stage s ON c.fileid = s.fileid AND s.date_of_stage < c.dt
    GROUP BY c.fileid,
             c.dt,
             c.cash;
    
        FILEID DT                CASH MAX_DATE
    ---------- ----------- ---------- -----------
             1 03/04/2017          50 06/04/2016
             2 08/07/2015         100 
             3 14/09/2018          70 
    

    【讨论】:

      【解决方案3】:

      这很奇怪。使用您提供的“检查”查询的数据可以正常工作并显示两行。这是dbfiddle demo

      无论如何,如果您只需要从第二个表中附加最大日期,请使用简单的子查询:

      select fileID,  date_, cash, 
             (select max(date_of_stage) 
                from stage s
                where fileid = c.fileid and s.date_of_stage < c.date_) as max_date
        from cash c
      

      demo

      【讨论】:

        猜你喜欢
        • 2017-09-02
        • 2010-11-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-28
        • 2017-12-07
        相关资源
        最近更新 更多