在大查询中进行滚动聚合的更好方法?

Posted

技术标签:

【中文标题】在大查询中进行滚动聚合的更好方法?【英文标题】:better way to do a rolling aggregation in big query? 【发布时间】:2018-08-14 15:27:40 【问题描述】:

我有一些用 BigQuery 编写的 SQL 代码,它对三天前的当前日期的值进行滚动求和。

with weekly_agg AS
(
select 
    * ,
    UNIX_SECONDS(TIMESTAMP(event_date)) as timestamps
from
    test.window_test
order by event_date
)
select 
    country,
    event_date
    sum(value) over (partition by country order by timestamps range between 259200 PRECEDING AND CURRENT ROW) as rolling
from
     weekly_agg 

这似乎是一个冗长的解决问题的方法,有没有更好的方法来完成同样的事情?第一个限制是您需要硬编码值 259200(3 天),您无法输入诸如 ((3600 * 24) * 3) 之类的计算。如果我能在分区部分做一个日期范围会更好。

【问题讨论】:

data typeevent_date 到底是什么? 它是日期类型,最大的问题是在分区内,有没有办法使用日期而不是数字之间的范围? 【参考方案1】:

第一个限制是您需要硬编码值 259200(3 天),您无法输入诸如 ((3600 * 24) * 3) 之类的计算

以下仅使用3 days

#standardSQL
WITH weekly_agg AS (
  SELECT 
    * ,
    DATE_DIFF(event_date, '2000-01-01', DAY) AS day
  FROM `test.window_test`
  ORDER BY event_date
)
SELECT 
  country,
  event_date,
  SUM(value) OVER(PARTITION BY country ORDER BY day RANGE BETWEEN 3 PRECEDING AND CURRENT ROW) AS rolling
FROM weekly_agg    

有没有办法使用日期而不是数字之间的范围?

如果您将使用日期而不是范围 - 这将是一些其他逻辑(不是 rolling aggregation) - 类似于简单的分组 - 例如

SELECT 
  country,
  event_date,
  SUM(value) 
FROM weekly_agg  
WHERE event_date BETWEEN <date1> AND <date2>
GROUP BY country, event_date   

但这很可能不是你想要的......

【讨论】:

这很好,但有没有不硬编码 3 而是使用变量? 它必须是文字或参数。 UI 中不支持参数 - 但 API、CLI 和客户端支持 - cloud.google.com/bigquery/docs/parameterized-queries

以上是关于在大查询中进行滚动聚合的更好方法?的主要内容,如果未能解决你的问题,请参考以下文章

sql查询聚合与聚合和查询OLAP多维数据集的区别

Datastore 存储聚合嵌套数据以更好地查询的最佳方式

聚合查询中的性能更新

LINQ to SQL:对来自订购系统的多个表的报告的聚合数据进行复杂查询

如何在 Promscale 的聚合查询中对标签进行分组

google bigquery SQL group by 聚合函数