BigQuery:如何在滚动时间戳窗口内对行进行分组和计数?
Posted
技术标签:
【中文标题】BigQuery:如何在滚动时间戳窗口内对行进行分组和计数?【英文标题】:BigQuery: how to group and count rows within rolling timestamp window? 【发布时间】:2016-10-27 16:01:13 【问题描述】:我有一些使用 MongoDB 的经验,并且正在学习 BigQuery。我正在尝试执行以下任务,但我不知道如何使用 BigQuery 的标准 SQL 来完成。
我有一张包含以下数据的表格。它包含在不同网站 url 上发生的事件。时间戳表示给定事件发生的时间。例如,第一行表示“事件 'xx' 在 2016 年 10 月 18 日 15:55:16 UTC 发生在 url 'a.html' 上。”
event_id | url | timestamp
-----------------------------------------------------------
xx a.html 2016-10-18 15:55:16 UTC
xx a.html 2016-10-19 16:68:55 UTC
xx a.html 2016-10-25 20:55:57 UTC
yy b.html 2016-10-18 15:58:09 UTC
yy a.html 2016-10-18 08:32:43 UTC
zz a.html 2016-10-20 04:44:22 UTC
zz c.html 2016-10-21 02:12:34 UTC
我想在滚动的 3 天窗口内计算每个网址上发生的每个事件的数量。换句话说,我希望能够说以下内容:
“在 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”将发生约 10,000 次,事件“zz”将发生约 0-2 次。
鉴于我有限的 SQL 知识,我不想为结果表提供结构,因为我认为这可能会错误地限制可能的答案。谢谢!
【问题讨论】:
查看***.com/a/49866033/132438 以获取具有近似结果的更快解决方案 - 以防您还需要滚动计数唯一性。 【参考方案1】:以下是 BigQuery 标准 SQL(请参阅 Enabling Standard 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? (我们能否以某种方式将 AT TIME ZONE "America/New_York" 与 DATE(ts) 一起使用?)再次感谢...我是 BigQuery 和 SQL 的菜鸟。 另外,这段代码很好用。需要注意的是,它提供了一个 4 天的窗口,我可以轻松地将其调整为 3 天。 1) 当然 - 每日汇总是有意义的,因为最初的问题是如何制定的(3 个滚动DAYS
)。所以很容易修改N分钟。让我知道您是否想要示例,否则您将自己尝试。 2) 轻松 - 见cloud.google.com/bigquery/sql-reference/data-types#time-zones以上是关于BigQuery:如何在滚动时间戳窗口内对行进行分组和计数?的主要内容,如果未能解决你的问题,请参考以下文章
您能否创建一个 BigQuery UDF 来生成表列表,而不是对行进行操作?
当您的数据不在偶数时间间隔内时,是不是有一种快速方法可以在偶数时间间隔内对 Pandas Dataframe 进行滚动求和?