#sql #join #snowflake-cloud-data-platform #sql-date-functions #sqldatetime
Вопрос:
Привет, у меня есть две таблицы, к которым я должен присоединиться в поле ID, а затем в ближайшую дату ( только если дата находится в пределах одного часового диапазона больше или меньше), причина в том, что обе таблицы не обновляются одновременно, поэтому время между ними немного ( но максимальная задержка составляет 1 час). Пожалуйста, смотрите пример ниже:
Таблица 1:
ID Start_Date End_Date
1 1/14/2021 14:34 1/27/2021 10:31
1 2/4/2021 10:40 7/2/2021 13:01
2 8/2/2020 00:04 9/7/2020 11:26
2 11/4/2020 9:24 2/8/2021 16:22
Таблица 2:
ID Start_date End_Date
1 1/14/2021 13:47 1/27/2021 10:24
2 8/1/2020 23:57 9/7/2020 11:22
2 11/4/2020 9:12 2/8/2021 16:20
В этом примере: запись 1 из таблицы 1 должна присоединиться к записи 1 из таблицы 2.
записи 2 из таблицы 1 не должны присоединяться к таблице 2 ( поскольку для этого идентификатора нет записи в течение 1 часа с даты начала), запись 3,4 должна присоединяться к записи 3,4 в таблице 2 соответственно.
Комментарии:
1. Интересный вопрос.
Ответ №1:
Отказ от ответственности: Я не эксперт по снежинке, и у меня нет никакого способа протестировать решение, описанное ниже.
Предполагая, что вы можете использовать стандартный SQL в Snowflake, приведенный ниже запрос предварительно вычисляет разницу во времени между датами начала возможных связанных строк и ранжирует их от самого низкого до самого высокого. Наименьшая (минимальная разница во времени) выигрывает объединение.
Вы можете сделать:
select *
from (
select
a.*,
b.*,
row_number() over(
partition by a.id
order by abs(timediff(second, a.start_date, b.start_date))
) as rn
from table1 a
join table2 b on a.id = b.id
and a.start_date between dateadd(hour, -1, b.start_date)
and dateadd(hour, 1, b.start_date)
) x
where rn = 1
Ответ №2:
Другим вариантом может быть:
select * from table_1 inner join table_2 on table_1.id = table_2.id
where DATEADD(hour,1,table_1.d_1) between table_2.d_1 and table_2.d_2
or DATEADD(hour,-1,table_1.d_2) between table_2.d_1 and table_2.d_2
Полный код вы можете вырезать/вставить в snowflake и запустить 🙂
with table_1 as (
select 1 id, TO_TIMESTAMP('1/14/2021 14:34', 'mm/dd/yyyy hh24:mi' ) d_1, TO_TIMESTAMP('1/27/2021 10:31', 'mm/dd/yyyy hh24:mi' ) d_2
union select 1 id, TO_TIMESTAMP('2/4/2021 10:40', 'mm/dd/yyyy hh24:mi' ) d_1, TO_TIMESTAMP('7/2/2021 13:01', 'mm/dd/yyyy hh24:mi' ) d_2
union select 2 id, TO_TIMESTAMP('8/2/2020 00:04', 'mm/dd/yyyy hh24:mi' ) d_1, TO_TIMESTAMP('9/7/2020 11:26', 'mm/dd/yyyy hh24:mi' ) d_2
union select 2 id, TO_TIMESTAMP('11/4/2020 9:24', 'mm/dd/yyyy hh24:mi' ) d_1, TO_TIMESTAMP('2/8/2021 16:22', 'mm/dd/yyyy hh24:mi' ) d_2 )
, table_2 as (
select 1 id, TO_TIMESTAMP('1/14/2021 13:47', 'mm/dd/yyyy hh24:mi' )
d_1, TO_TIMESTAMP('1/27/2021 10:24', 'mm/dd/yyyy hh24:mi' ) d_2
union select 2 id, TO_TIMESTAMP('8/1/2020 23:57', 'mm/dd/yyyy hh24:mi' ) d_1, TO_TIMESTAMP('9/7/2020 11:22', 'mm/dd/yyyy hh24:mi' ) d_2
union select 2 id, TO_TIMESTAMP('11/4/2020 9:12', 'mm/dd/yyyy hh24:mi' ) d_1, TO_TIMESTAMP(' 2/8/2021 16:20', 'mm/dd/yyyy hh24:mi' ) d_2 )
select * from table_1 inner join table_2 on table_1.id = table_2.id
where DATEADD(hour,1,table_1.d_1) between table_2.d_1 and table_2.d_2
or DATEADD(hour,-1,table_1.d_2) between table_2.d_1 and table_2.d_2