【发布时间】:2017-12-19 11:30:42
【问题描述】:
我们一直在努力循环(标准 sql)BigQuery 中的数据,但没有成功。
我不确定这是否是 sql 支持的功能、我们对问题的理解或我们想要在 BigQuery 中执行此操作的方式。
无论如何,假设我们有一个事件表,其中每个事件由一个用户 ID 和一个日期描述(同一用户 ID 在同一日期可能有许多事件)
id STRING
dt DATE
我们想知道的一件事是在给定的时间段内有多少不同的用户生成了事件。这是相当微不足道的,只是在 WHERE 子句中以句点作为约束的表上的一个 COUNT。例如,如果我们有四个月作为我们的时间段:
SELECT
COUNT(DISTINCT id) AS total
FROM
`events`
WHERE
dt BETWEEN DATE_ADD(CURRENT_DATE(), INTERVAL -4 MONTH)
AND CURRENT_DATE()
但是,如果我们希望在相同的给定时间段内递归地获取其他几天(或几周)的历史记录,我们的问题就来了。例如,对于昨天、前天等……直到……例如,3 个月前。所以这里的变量是 CURRENT_DATE() ,它可以追溯到一天或任何一个因素,但间隔保持不变(在我们的例子中,4 个月)。我们期待这样的事情(以一天为因子):
2017-07-14 2017-03-14 1760333
2017-07-13 2017-03-13 1856333
2017-07-12 2017-03-12 2031993
...
2017-04-14 2017-01-14 1999352
这只是对同一张表上的每一天、每一周等进行循环,然后对该时间段内发生的不同事件进行计数。但我们不能在 BigQuery 中执行“循环”。
我们认为的一种方法是 JOIN,然后是 GROUP BY 间隔上的 COUNT(利用 HAVING 子句来模拟从给定日期到 4 个月的时间段),但这是非常低效的,它只是没有'永远不会考虑表的大小(它有大约 2.54 亿条记录,截至今天为 173 GB,并且每天都在不断增长)。
我们认为的另一种方法是使用 UDF,其想法是我们将日期间隔列表提供给函数,然后我们的函数将为每个返回间隔和该间隔的计数的间隔应用朴素查询(用于计数)。但是...... BigQuery 中的 UDF 不支持访问 UDF 中的表,因此我们必须将整个表提供给我们尚未尝试但似乎不合理的 UDF。
因此,我们没有想到基本上迭代相同数据并对 BigQuery 中的部分数据(如您所见的重叠部分)进行计算的解决方案,我们唯一的解决方案是在 BigQuery 之外执行此操作(结束)。
有没有办法或有人可以想办法在 BigQuery 中完成这一切?我们的目标是将其作为 BigQuery 内部的视图提供,以便它不依赖于需要以我们设置的频率(天/周/等)触发的外部系统。
【问题讨论】:
-
SQL 没有循环。您应该能够使用分析函数,即
OVER (PARTITION)和RANGEcloud.google.com/bigquery/docs/reference/standard-sql/…。开始 -> stackoverflow.com/questions/29899097/… -
GENERATE_DATE_ARRAY应该让您在日期上创建一个“循环”。除非其他人先添加答案,否则我稍后会尝试添加答案。 -
@ElliottBrossard - 为时已晚。米哈伊尔打败了你 ;-) 感谢你把我指向
GENERATE_DATE_ARRAY- 从来不知道它存在! -
@GrahamPolley,当然非常清楚这一点,我们只是试图通过与自身交叉连接来模拟它。但正是交叉连接带来了麻烦(我想是性能方面的),而一种聪明的做法是我们还没有弄清楚,我也没有找到很多例子。正如@ElliottBrossard 指出的那样,
GENERATE_DATE_ARRAY似乎是可能的,但是在尝试了下面@Will 的建议后,我们得到了我作为评论指出的错误(并且寻找该错误表明解决问题的另一种方法)。
标签: google-bigquery user-defined-functions