Улей соединение между двумя таблицами - PullRequest
0 голосов
/ 03 марта 2020

Это проблема: у меня есть эта промежуточная таблица:

key0    key1    timestamp   partition_key
5   5   2020-03-03 14:42:21.548 1
5   4   2020-03-03 14:40:11.871 1
4   3   2020-03-03 14:43:47.602 2

И эта целевая таблица:

key0    key1    timestamp   partition_key
5   4   2020-03-03 13:43:16.695 1
5   5   2020-03-03 13:45:24.793 1
5   2   2020-03-03 13:47:30.668 1
5   1   2020-03-03 13:48:30.669 1
4   3   2020-03-03 13:53:47.602 2
43  3   2020-03-03 14:00:14.016 2

Я хочу получить этот вывод:

key0    key1    timestamp   partition_key
5   5   2020-03-03 14:42:21.548 1
5   4   2020-03-03 14:40:11.871 1
5   2   2020-03-03 13:47:30.668 1
5   1   2020-03-03 13:48:30.669 1
4   3   2020-03-03 14:43:47.602 2
43  3   2020-03-03 14:00:14.016 2

В поле метки времени я хочу самую последнюю запись, когда key0, key1 и partition_key. Кроме того, мне нужны уже существующие записи в целевой таблице, но их нет в промежуточной таблице

Сначала я попытался выполнить этот запрос:

select 
t1.key0,
t1.key1,
t1.timestamp,
t2.partition_key
from staging_table t2 
left outer join target_table t1 on 
t1.key0=t2.key0 AND
t1.key1=t2.key1 AND
t1.timestamp=t2.timestamp; 






Ответы [ 3 ]

3 голосов
/ 03 марта 2020

Это похоже на запрос расстановки приоритетов - возьмите все из промежуточных, а затем несопоставленных строк из цели. Я собираюсь порекомендовать union all:

select s.*
from staging s
union all
select t.*
from target t left join
     staging s
     on t.key0 = s.key0 and t.key1 = s.key1
where s.key0 is null;

Предполагается, что в постановке используются самые последние строки, что верно в данных образца. Если нет, я бы сформулировал это следующим образом:

select key0, key1, timestamp, partition_key
from (select st.*,
             row_number() over (partition by key0, key1 order by timestamp desc) as seqnum
      from ((select s.* from source s
            ) union all
            (select t.* from target t
            )
           ) st
     ) st
where seqnum = 1;
1 голос
/ 03 марта 2020

Я думаю, что вы просто хотите left join и coalesce():

select 
    t.key0,
    t.key1,
    coalesce(s.timestamp, t.timestamp) timestamp,
    t.partition_key
from target_table t 
left join  staging_table s 
    on  s.key0 = t2.key0 
    and s.key1 = t.key1 
    and s.partition_key = t.partition_key

Для каждой записи в target_table, это ищет запись в staging_table, которая имеет тот же (key0, key1, partition_key). Если такая запись доступна, мы используем ее timestamp вместо timestamp из target_table.

1 голос
/ 03 марта 2020

Вам нужно FULL JOIN:

select COALESCE(t1.key0, T2.key0) AS key0, COALESCE(t1.key1, T2.KEY1) AS KEY1,
       COALESCE(t1.timestamp, T2.timestamp) AS timestamp, 
       COALESCE(t1.partition_key, t2.partition_key) AS partition_key
t2.partition_key
from staging_table t2 FULL JOIN 
     target_table t1
     on t1.key0 = t2.key0 AND t1.key1 = t2.key1 AND
        t1.timestamp = t2.timestamp; 
...