【问题标题】:Join on closest date in SQL在 SQL 中加入最近的日期
【发布时间】:2021-07-07 16:08:02
【问题描述】:

嗨,我有两个表,我必须在 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 应连接到表 2 中的记录 1。

表 1 中的记录 2 不应加入表 2(因为该 ID 的开始日期 1 小时内没有记录) 记录 3,4 应该分别加入 table2 中的记录 3,4。

【问题讨论】:

  • 有趣的问题。

标签: sql join snowflake-cloud-data-platform sql-date-functions sqldatetime


【解决方案1】:

免责声明:我不是 Snowflake 方面的专家,也无法测试下面描述的解决方案。

假设您可以在 Snowflake 中使用标准 SQL,下面的查询会预先计算可能相关行的开始日期之间的时间差,并将它们从最低到最高排列。最低(最小时间差)赢得加入。

你可以这样做:

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
    

    您可以将完整代码剪切/粘贴到雪花中并运行 :-)

    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 
    

    【讨论】:

      猜你喜欢
      • 2020-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-18
      • 1970-01-01
      • 1970-01-01
      • 2012-03-01
      • 1970-01-01
      相关资源
      最近更新 更多