Оставлено соединение не дает результатов - PullRequest
0 голосов
/ 26 июня 2018

У меня есть запрос ниже, где мне нужно иметь все записи из первой таблицы1 и соответствующее значение для table2.If значение не там NULL, чтобы быть возвращенным. Но я получаю только общие записи, возвращенные в результате.

select 

distinct s1.src_sys_id schema_nm,
to_date(CAST(CAST(s3.execn_ts AS BIGINT)/1000 AS TIMESTAMP)) as maxtime
from table1 s1

LEFT JOIN table2 s3 ON s1.src_sys_id = s3.src_sys_id

INNER JOIN 
(
  SELECT src_sys_id, max(execn_ts) as maxtime
  FROM table2
  GROUP BY src_sys_id 
) s2 on s2.src_sys_id = s1.src_sys_id and s1.execn_ts = s2.maxtime  

table1

schema_nm   
GA1P    
GG60    
GGDD    
GWY1    
GXO1    
GYY1    
GHOD    

table2

schema_nm   execn_ts
GA1P    10/1/2018
GG60    10/2/2018
GGDD    10/3/2018

Текущие результаты

schema_nm   maxtime
GA1P    10/1/2018
GG60    10/2/2018
GGDD    10/3/2018

Ожидаемые результаты

schema_nm   maxtime
GA1P    10/1/2018
GG60    10/2/2018
GGDD    10/3/2018
GWY1    NULL
GXO1    NULL
GYY1    NULL
GHOD    NULL

Ответы [ 2 ]

0 голосов
/ 26 июня 2018

Ваш первый LEFT JOIN избыточен:

select s1.src_sys_id schema_nm,
       to_date(CAST(CAST(s2.execn_ts AS BIGINT)/1000 AS TIMESTAMP)) as maxtime
from table1 s1 left join (
     select s2.src_sys_id, max(s2.execn_ts) as execn_ts
     from table2 s2
     group by s2.src_sys_id
) s2 on s1.src_sys_id = s2.src_sys_id; 
        --s2.execn_ts = s1.execn_ts;
0 голосов
/ 26 июня 2018

Я думаю, что ответом на ваш настоящий вопрос является использование оконных функций:

select s1.src_sys_id schema_nm,
       to_date(CAST(CAST(s3.execn_ts AS BIGINT)/1000 AS TIMESTAMP)) as maxtime
from table1 s1 left join
     (select s2.*,
             row_number() over (partition by s2.src_sys_id order by s2.execn_ts desc) as seqnum
      from table2 s2
     ) s2
     on s1.src_sys_id = s2.src_sys_id and s2.seqnum = 0;

Причина, по которой ваш запрос отфильтровывает строки, немного сложна. left join в порядке. Даже inner join в порядке. , , насколько это возможно. Однако оба объединения находятся в одной таблице. Таким образом, если соответствующая строка не существует для первого join, то для второго не существует строки.

Другими словами, inner join отфильтровывает те же строки, что и несопоставленные строки в left join.

Все вышесказанное, оконные функции - лучший подход, хотя повторное использование left join также решит вашу проблему.

...