收集对日期分区表的查询的每日结果
Posted
技术标签:
【中文标题】收集对日期分区表的查询的每日结果【英文标题】:Collecting per-day results for queries over date-partitioned tables 【发布时间】:2017-12-21 15:41:10 【问题描述】:我在 BigQuery 中有一些名称为 counts_20171220
的表,其中的行采用这种格式(每个日期每个 contentId
只有一行):
| contentId | views |
+-----------+-------+
| cb32edc0 | 728324|
| 52cbb1ff | 643220|
...
我想为给定时间范围内的给定contentId
生成查看计数列表,没有间隙,例如:
| date | views |
+------------+--------+
| 2017-12-01 | NULL | -- or 0
| 2017-12-02 | NULL | -- or 0
| 2017-12-03 | 728314 |
| 2017-12-04 | 328774 |
| 2017-12-05 | 28242 |
...
| 2017-12-20 | NULL | -- or 0
为了做到这一点,我想我需要使用*
和_table_suffix
,但我无法弄清楚如何包含没有该contentId
条目的日期。我得到的最接近的是这个查询:
#standardSQL
SELECT
_table_suffix AS date,
ARRAY_AGG(views) AS views
FROM
`test.counts_*`
WHERE
_table_suffix BETWEEN '20171201' AND '20171220'
AND contentId = 'cb32edc0'
GROUP BY
_table_suffix,
contentId
ORDER BY
date
这个查询的问题是
-
它不包含所有日期的行,仅包含表中包含
contentId
'cb32edc0' 条目的日期
由于它的结构方式,我需要使用(这里没用的)聚合函数来提取views
我应该如何构建这样的查询?我很乐意获得有关此查询的具体帮助以及有关如何实现此类查询日期分区表的一般指示。
【问题讨论】:
【参考方案1】:这应该可行,假设每个日期至少有一行:
SELECT
PARSE_DATE('%Y%m%d', _TABLE_SUFFIX) AS date,
IFNULL(MAX(IF(contentId = 'cb32edc0', views, NULL)), 0) AS views
FROM `test_counts_*`
WHERE _TABLE_SUFFIX BETWEEN '20171201' AND '20171220'
GROUP BY date;
它不是显式过滤与所需contentId
不匹配的行,而是使用带有聚合函数的条件将它们从结果中排除。如果组中没有具有所需contentId
的行,IFNULL
确保表达式返回0
而不是NULL
。
【讨论】:
谢谢!这实际上相当优雅!以上是关于收集对日期分区表的查询的每日结果的主要内容,如果未能解决你的问题,请参考以下文章
oracle数据量巨大表查询时间太长,sqlplus有的不能spool出结果