如何计算 BigQuery 中日期间隔联合的重叠

Posted

技术标签:

【中文标题】如何计算 BigQuery 中日期间隔联合的重叠【英文标题】:How to work out overlap of the union of date intervals in BigQuery 【发布时间】:2021-08-12 15:00:51 【问题描述】:

在 BigQuery 中,给定一个日期间隔表,我如何找到它们的并集与单个感兴趣的日期间隔的重叠?

例如,给定一个日期间隔表(称此表 A)为:

         start_date     end_date

         2021-02-01   2021-05-01    
         2021-04-01   2021-07-01  
         2020-12-01   2021-03-01 
         2021-09-01   2021-12-01    

而感兴趣的单个日期间隔(称为此表 B)为:

         start_date     end_date

         2021-01-01   2021-11-01     

我想计算 A 中的间隔与 B 中的间隔之间的重叠为 8 个月

当 A 的区间不相交时,我可以用以下方法解决这个问题:

SELECT
    SUM(GREATEST(0, DATE_DIFF(LEAST(B.end_date, A.end_date), 
                              GREATEST(B.start_date,A.start_date), MONTH))) 
    AS months_overlap
FROM 
    A, B

问题出现在 A 中的日期间隔相互重叠时,如上例所示,在这种情况下,上面的代码双重计算 A 中的重叠间隔,即它将返回 10 个月上面的例子。

关于如何在不重复计算的情况下计算这些间隔的重叠有什么建议吗?我曾考虑将 Lags 引入日期差异函数,但我做错了。

【问题讨论】:

【参考方案1】:

考虑以下方法

select count(1) as months_overlap
from (
  select distinct date_trunc(day, month) month
  from tableA, unnest(generate_date_array(start_date, end_date - 1)) day
)
join (
  select distinct date_trunc(day, month) month
  from tableB, unnest(generate_date_array(start_date, end_date - 1)) day
)
using(month)          

如果应用于您问题中的样本数据 - 输出是

【讨论】:

【参考方案2】:

一种方法是将各种间隔扩展为月,加入并计数:

with b as (
      select mon
      from b cross join
           unnest(generate_date_array(b.start_date, b.end_date, interval 1 month)) mon
     ),
     a as (
      select mon
      from a cross join
           unnest(generate_date_array(a.start_date, a.end_date, interval 1 month)) mon
     )
select count(distinct mon)
from a join
     b
     using (mon);

【讨论】:

以上是关于如何计算 BigQuery 中日期间隔联合的重叠的主要内容,如果未能解决你的问题,请参考以下文章

BigQuery 选择时间间隔内的数据

BigQuery 中的重叠间隔计数

如何计算两个(年-月-日)中间的间隔天数

VB计算两个日期时间的间隔

怎样在EXCEL计算两个日期中间间隔几年几个月几天

怎么用excel计算两个日期之间的间隔年限?