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) 中的一个/多个事件中获取多个参数的唯一计数