【问题标题】:Merge when date is within a date range in another dataset in SQL当日期在 SQL 中另一个数据集中的日期范围内时合并
【发布时间】:2021-04-17 07:20:41
【问题描述】:

我有 2 个数据集:A 和 B

数据集 A:

Date        | Age 
_____________________
31/3/2015   | 21
31/8/2015   | 30

数据集 B:

StartDate   | Income
_____________________
30/3/2015   | 1k
31/7/2015   | 2k
1/10/2015   | 3k

如何合并数据集 A 和 B(左连接 B),例如,数据集 A 中的日期 31/8/2015 位于数据集 B 中 31/7/2016 和 1/10/2015 的日期范围内. 所以在 2015 年 8 月 31 日,收入将是 2k。

最终结果应如下所示:

Date        | Age  | Income
__________________________________________
31/3/2015   | 21   | 1k
31/8/2015   | 30   | 2k

【问题讨论】:

标签: sql sql-server date join merge


【解决方案1】:

看起来相关子查询是做你想做的事情的一种方式。在标准 SQL 中,这看起来像:

select a.*,
       (select b.income
        from b
        where b.date <= a.date
        order by b.date desc
        fetch first 1 row only
       ) as income
from a;

注意:并非所有数据库都支持fetch first 子句。都支持类似的功能,使用limitselect top 或类似的东西。

如果您愿意,也可以采用不同的方法。如果第二个表有 范围 收入已知而不是单个日期,那么您可以使用连接:

select a.*, b.income
from a left join
     (select b.*, lead(date) over (order by date) as next_date
      from b
     ) b
     on b.date <= a.date and
        (b.next_date is null or b.next_date > a.date);

这种方法的优点是更容易从b获取多列。

【讨论】:

    【解决方案2】:

    您需要 A 的记录和表 B 中 A 的最新但最少的日期。

    您可以将分析函数用作流:

    select * from
    (select a.*, B.*,
           row_number() over (partition by a.date order by b.start_date desc) as rn
      from tablea a join tableb b on a.date > b.start_date) t
    where rn = 1
    

    -- 更新

    我认为您想要 B 的记录和下一条记录,然后将其与 A 进行比较,然后您可以使用LEAD,如下所示:

    select a.*, b.start_date, b.income
      from tablea a 
      join (select b.*, lead(start_date) over (order by start_date) as end_Date 
              from tableb b) b 
        on a.date between b.start_Date and b.end_date 
        or (a.date > b.start_date and b.end_Date is null)
    

    【讨论】:

    • 您可以使用leaddefault 参数将其设置为无穷大,如lead(start_date, 1, date '9999-12-31') 并删除OR 条件。也应该只包括间隔的一端(我更喜欢start_date),因为对于between,您将有两个输出值date = start_date 的某个间隔。
    猜你喜欢
    • 1970-01-01
    • 2019-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-23
    相关资源
    最近更新 更多