【问题标题】:Count of overlapping intervals in BigQueryBigQuery 中的重叠间隔计数
【发布时间】: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 排序时)。事实上,在我拥有的数据集上,它超时了。有没有更好的方法来实现这一点?

【问题讨论】:

  • 你能解释一下输出吗?
  • 输出是输入的每个间隔的开始时间以及在该开始时间的打开间隔(开始时间=那个时间的行)的计数间隔。

标签: sql google-bigquery


【解决方案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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多