Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql BigQuery:如何在滚动时间戳窗口中对行进行分组和计数?_Sql_Google Bigquery - Fatal编程技术网

Sql BigQuery:如何在滚动时间戳窗口中对行进行分组和计数?

Sql BigQuery:如何在滚动时间戳窗口中对行进行分组和计数?,sql,google-bigquery,Sql,Google Bigquery,我有一些MongoDB的经验,我正在学习BigQuery。我正在尝试执行以下任务,但我不知道如何使用BigQuery的标准SQL来执行 我有一个包含以下数据的表。它包含发生在不同网站URL上的事件。时间戳表示给定事件发生的时间。例如,第一行表示“事件‘xx’发生在2016-10-18 15:55:16 UTC的url‘a.html’上。” 我想计算在3天的滚动窗口内每个url上发生的每个事件的数量。换句话说,我想说的是: “在url‘a.html’上,在[2016-10-18 00:00:00

我有一些MongoDB的经验,我正在学习BigQuery。我正在尝试执行以下任务,但我不知道如何使用BigQuery的标准SQL来执行

我有一个包含以下数据的表。它包含发生在不同网站URL上的事件。时间戳表示给定事件发生的时间。例如,第一行表示“事件‘xx’发生在2016-10-18 15:55:16 UTC的url‘a.html’上。”

我想计算在3天的滚动窗口内每个url上发生的每个事件的数量。换句话说,我想说的是:

  • “在url‘a.html’上,在[2016-10-18 00:00:00 UTC,2016-10-21 00:00:00 UTC]的时间间隔内,事件‘xx’发生了两次。”

  • “在url‘a.html’上,在[2016-10-19 00:00:00 UTC,2016-10-22 00:00:00 UTC]间隔期间,事件‘xx’发生一次。”

  • “在url‘a.html’上,在[2016-10-20 00:00:00 UTC,2016-10-23 00:00:00 UTC]的时间间隔内,事件‘xx’发生了零次。”(注意:这不需要作为一行返回。缺少此行可能意味着事件发生了零次。)

一些注意事项:我的数据库每天包含超过10万行,事件的发生率各不相同。这意味着,在1天内,事件“xx”将发生约10000次,事件“zz”将发生约0-2次


鉴于我有限的SQL知识,我不想为结果表提供结构,因为我认为这可能会错误地限制可能的答案。谢谢!

下面是BigQuery标准SQL(请参阅

我使用
ts
作为字段名(而不是您的示例中的
timestamp
),并假设此字段为
timestamp
数据类型

WITH dailyAggregations AS (
  SELECT 
    DATE(ts) AS day, 
    url, 
    event_id, 
    UNIX_SECONDS(TIMESTAMP(DATE(ts))) AS sec, 
    COUNT(1) AS events 
  FROM yourTable
  GROUP BY day, url, event_id, sec
)
SELECT 
  url, event_id, day, events, 
  SUM(events) 
    OVER(PARTITION BY url, event_id ORDER BY sec 
      RANGE BETWEEN 259200 PRECEDING AND CURRENT ROW
  ) AS rolling3daysEvents
FROM dailyAggregations
-- ORDER BY url, event_id, day

259200的值实际上是3x24x3600,因此设置了3天的范围,因此您可以设置您需要的任何实际滚动周期

这是可行的,让我看看我是否完全理解:1)创建一个按天对事件进行分组和计数的中间表。它还将时间戳字段转换为其unix秒等效值。2)使用以秒为单位的窗口汇总事件?当然,如果需要,还可以询问两个问题:1)是否可以在没有中间每日聚合的情况下执行此操作?(即:假设我们希望窗口为10分钟,而不是3天)。2)是否可以修改查询,使一天的概念不仅与UTC有关,而且与特定时区有关?(我们是否可以在时区“America/New_York”中使用日期(ts)再次感谢……我对BigQuery和SQL很在行。另外,这段代码也很有用。顺便说一句,它提供了一个4天的窗口,我可以轻松调整为3天。1)确定-每天的聚合是有意义的,因为最初的问题是如何制定的(3天)。因此,可以轻松地修改N分钟。如果您想要示例,请让我知道,否则您将自己尝试。2)简单-请参阅查看,以获得具有近似结果的更快解决方案-如果您还需要单数的滚动计数。
WITH dailyAggregations AS (
  SELECT 
    DATE(ts) AS day, 
    url, 
    event_id, 
    UNIX_SECONDS(TIMESTAMP(DATE(ts))) AS sec, 
    COUNT(1) AS events 
  FROM yourTable
  GROUP BY day, url, event_id, sec
)
SELECT 
  url, event_id, day, events, 
  SUM(events) 
    OVER(PARTITION BY url, event_id ORDER BY sec 
      RANGE BETWEEN 259200 PRECEDING AND CURRENT ROW
  ) AS rolling3daysEvents
FROM dailyAggregations
-- ORDER BY url, event_id, day