分析具有过多波动性的数据系列趋势很难。在许多情况下,使用平滑技术(例如移动平均值或移动总和)很有用。有很多工具可以执行此类操作,但是当我们讨论数百万行时,直接在Google Big Query等云环境中进行操作非常有用。
我的问题是:如何在Google Big Query上计算移动金额/平均值?
答案 0 :(得分:3)
以下是BigQuery Standard SQL
#standardSQL
SELECT
pickup_date,
number_of_trip,
AVG(number_of_trip) OVER (ORDER BY day RANGE BETWEEN 6 PRECEDING AND CURRENT ROW) AS mov_avg_7d,
AVG(number_of_trip) OVER (ORDER BY day RANGE BETWEEN 27 PRECEDING AND CURRENT ROW) AS mov_avg_28d
FROM (
SELECT
DATE(pickup_datetime) AS pickup_date,
UNIX_DATE(DATE(pickup_datetime)) AS day,
COUNT(*) AS number_of_trip
FROM `nyc-tlc.yellow.trips`
GROUP BY 1, 2
)
WHERE pickup_date>'2013-01-01'
乍一看 - 这个答案看起来与OP的答案非常相似,所以只有几条关于这个答案如何不同的评论:
首先(也是最不重要的) - BigQuery Team强烈建议使用BigQuery Standard SQL - 除非有充分的理由使用Legacy SQL - 例如因为范围快照或者特定于遗留sql的东西
其次,最重要的是 - 在这种情况下使用OVER和ROWS并不是最好的选择,因为它计算的是行而不是天数,所以如果 - 偶然 - 任何给定的日子都会丢失 - 计算将使用最后8天和29天分别(而不是7和28)
在这种情况下,应该使用OVER和RANGE
答案 1 :(得分:1)
我花了很多时间研究这个答案但没有成功,所以我觉得与更多人分享是值得的。
解决方案:为了得到答案,我使用了Big Query的分析函数OVER
和ROWS
(https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators#analytic-function-syntax)。 Bellow有一个使用BigQuery中提供的公共数据的7天移动平均值和28天移动平均值的例子:
SELECT
pickup_date,
number_of_trip,
avg(number_of_trip) OVER (ORDER BY pickup_date ROWS BETWEEN 6 PRECEDING and CURRENT ROW) AS mov_avg_7d,
avg(number_of_trip) OVER (ORDER BY pickup_date ROWS BETWEEN 27 PRECEDING and CURRENT ROW) AS mov_avg_28d
FROM
(SELECT
date(pickup_datetime) as pickup_date,
count(*) as number_of_trip,
FROM [nyc-tlc:yellow.trips]
group each by 1
order by 1)
where pickup_date>'2013-01-01'
小心反模式!网上有很多帖子建议使用JOIN
甚至CROSS JOIN
来获得相同结果的解决方案。但是,根据Big Query文档(https://cloud.google.com/bigquery/docs/best-practices-performance-patterns),这些方法都是反模式。这意味着如果使用强力解决问题,对于大量数据性能将是一个问题。