【问题标题】:How to do a rolling sum in BigQuery for groups of weeks?如何在 BigQuery 中对数周进行滚动求和?
【发布时间】:2021-10-01 01:21:57
【问题描述】:
我有下表,其中包含两列:date 和 total_visits(网站访问量)。我需要计算两个新变量(滚动总和)。
-
Column_A:每天的滚动总和。对于每一天,我必须提供过去 14 天的总访问次数(不考虑当天)。当然,这个表中的前 14 天不可能有这个值,因为没有足够的前几天来计算这个值。
-
Column_B:每天的滚动总和。对于每一天,我必须提供考虑到当天前 4 周到 2 周之间的天数的总访问量。这意味着,例如,对于 2019-01-29,我们应该看到的值是 2021-01-01 和 2021-01-14 之间的总访问次数之和。当然,表中的前 28 天不会有该列的值,因为没有足够的数据来计算该值。
下表是一个例子:
我目前在 SQL (Workbench) 中有一个解决方案,但我需要将它应用于 GCP 中的数据库存储,并且存在我无法理解的语法差异。有什么提示吗?提前致谢
【问题讨论】:
标签:
sql
database
google-cloud-platform
google-bigquery
【解决方案1】:
考虑以下方法
select *,
if(dense_rank() over win <= 14, null, sum(total_visits) over rolling_last_14_day) as total_last_14_day,
if(dense_rank() over win <= 28, null, sum(total_visits) over rolling_between_4_and_2_weeks_ago) as total_between_4_and_2_weeks_ago
from `project.dataset.table`
window win as (order by unix_date(date)),
rolling_last_14_day as (win range between 14 preceding and 1 preceding),
rolling_between_4_and_2_weeks_ago as (win range between 28 preceding and 15 preceding)
如果应用于您问题中的样本数据 - 输出是
【解决方案2】:
如果你每天都有数据,那就用窗框吧:
select t.*,
(case when row_number() over (order by date) >= 14
then sum(total_visits) over (order by date rows between 13 preceding and current row)
end) as total_14_day,
(case when row_number() over (order by date) >= 28
then sum(total_visits) over (order by date rows between 27 preceding and 14 preceding)
end) as total_14_day
from t;