Left Join не возвращает недостающую информацию - SQL Oracle - PullRequest
0 голосов
/ 05 апреля 2019

Один предназначен для наличных , а другой - для этапа со следующей структурой

Наличных

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 

Мне нужен только максимум (date_of_stage), потому что это логически имеет смысл для нашего отчета, и это не частьвопрос в любом случае.

Дело в том: когда я сравниваю общую сумму денег из таблицы cash и вышеупомянутого выбора, я получаю немного меньшую общую сумму из вышеупомянутого выбора, чем из наличные стол (7 миллионов из наличные и 6,9 миллионов из вышеупомянутого выбора).Сейчас я пытаюсь определить недостающие записи, используя левое соединение:

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

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

Ответы [ 3 ]

0 голосов
/ 05 апреля 2019

Я думаю, что все, что вам нужно, это сделать левое внешнее соединение в исходном запросе, а не внутреннее соединение, например:

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 
0 голосов
/ 05 апреля 2019

Странно. С предоставленными вами данными ваш «проверочный» запрос работает нормально и показывает две строки. Вот демоверсия dbfiddle .

В любом случае, если вам нужно только прикрепить максимальную дату из второй таблицы, используйте простой подзапрос:

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

демо

0 голосов
/ 05 апреля 2019

попробуйте как показано ниже, изменив левый стол

 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
...