BigQuery 中的重叠间隔计数

Posted

技术标签:

【中文标题】BigQuery 中的重叠间隔计数【英文标题】:Count of overlapping intervals in BigQuery 【发布时间】:2017-04-10 15:28:42 【问题描述】:

给定一个区间表,我能否有效地查询每个区间开始时当前打开区间的数量(包括当前区间本身)?

例如,给定下表:

开始时间结束时间 1 10 2 5 3 4 5 6 7 11 19 20

我想要以下输出:

开始时间计数 1 1 2 2 3 3 5 3 7 2 19 1

在小型数据集上,我可以通过将数据集与自身结合来解决此问题:

WITH intervals AS (
  SELECT 1 AS start, 10 AS end UNION ALL
  SELECT 2, 5 UNION ALL
  SELECT 3, 4 UNION ALL
  SELECT 5, 6 UNION ALL
  SELECT 7, 11 UNION ALL
  SELECT 19, 20
)
SELECT 
  a.start_time,
  count(*)
FROM 
  intervals a CROSS JOIN intervals b
WHERE
  a.start_time >= b.start_time AND
  a.start_time <= b.end_time
GROUP BY a.start_time
ORDER BY a.start_time

对于大型数据集,CROSS JOIN 既不切实际又没有必要,因为任何给定的答案仅取决于少数前面的间隔(按start_time 排序时)。事实上,在我拥有的数据集上,它超时了。有没有更好的方法来实现这一点?

【问题讨论】:

你能解释一下输出吗? 输出是输入的每个间隔的开始时间以及在该开始时间的打开间隔(开始时间=那个时间的行)的计数间隔。 【参考方案1】:

... CROSS JOIN 既不切实际又不必要... 有没有更好的方法来实现这一点?

试试下面的 BigQuery 标准 SQL。不涉及 JOIN

#standardSQL
SELECT 
  start_time,
  (SELECT COUNT(1) FROM UNNEST(ends) AS e WHERE e >= start_time) AS cnt  
FROM (
  SELECT 
    start_time, 
    ARRAY_AGG(end_time) OVER(ORDER BY start_time) AS ends
  FROM intervals
)
-- ORDER BY start_time  

您可以使用下面的示例使用您问题中的虚拟数据来测试/玩它

#standardSQL
WITH intervals AS (
  SELECT 1 AS start_time, 10 AS end_time UNION ALL
  SELECT 2, 5 UNION ALL
  SELECT 3, 4 UNION ALL
  SELECT 5, 6 UNION ALL
  SELECT 7, 11 UNION ALL
  SELECT 19, 20 
)
SELECT 
  start_time,
  (SELECT COUNT(1) FROM UNNEST(ends) AS e WHERE e >= start_time) AS cnt  
FROM (
  SELECT 
    start_time, 
    ARRAY_AGG(end_time) OVER(ORDER BY start_time) AS ends
  FROM intervals
)
-- ORDER BY start_time

【讨论】:

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

Google BigQuery:如何查询两个不同值之间的共享值计数?

在 Firebase (BigQuery) 中的一个/多个事件中获取多个参数的唯一计数

如何从 bigquery 中的另一个表中获取短语列表的表字段中的匹配计数?

BigQuery 计算两个日期范围重叠

BigQuery 计算多列值之间的重叠百分比

BigQuery 中的相关计划 SQL 查询