用于28天滑动窗口聚合的BigQuery SQL(无需编写28行SQL)

ala*_*lan 7 sql sliding-window google-bigquery

我正在尝试使用LAG函数计算BigQuery中的28天移动总和.

这个问题的最佳答案

用于滑动窗口聚合的Bigquery SQL

来自Felipe Hoffa表示您可以使用LAG功能.一个例子是:

SELECT
    spend + spend_lagged_1day + spend_lagged_2day + spend_lagged_3day + ... +  spend_lagged_27day as spend_28_day_sum,
    user,
    date
FROM (
  SELECT spend,
         LAG(spend, 1) OVER (PARTITION BY user ORDER BY date) spend_lagged_1day,
         LAG(spend, 2) OVER (PARTITION BY user ORDER BY date) spend_lagged_2day,
         LAG(spend, 3) OVER (PARTITION BY user ORDER BY date) spend_lagged_3day,
         ...
         LAG(spend, 28) OVER (PARTITION BY user ORDER BY date) spend_lagged_day,
         user,
         date
  FROM user_spend
)
Run Code Online (Sandbox Code Playgroud)

有没有办法做到这一点,而不必写出28行SQL!

spr*_*ket 29

BigQuery文档没有很好地解释该工具支持的窗口函数的复杂性,因为它没有指定在ROWS或RANGE之后可以出现的表达式.它实际上支持窗口函数的SQL 2003标准,您可以在Web上找到其他位置,例如此处.

这意味着您可以通过单个窗口功能获得所需的效果.范围是27,因为它是当前包含在总和之前的行数.

SELECT spend,
       SUM(spend) OVER (PARTITION BY user ORDER BY date ROWS BETWEEN 27 PRECEDING AND CURRENT ROW),
       user,
       date
FROM user_spend;
Run Code Online (Sandbox Code Playgroud)

RANGE界限也非常有用.如果您的表缺少某些用户的日期,那么27个PRECEDING行将返回超过27天,但RANGE将根据日期值本身生成一个窗口.在以下查询中,日期字段是BigQuery TIMESTAMP,范围以微秒为单位指定.我建议每当你在BigQuery中使用这样的数学日期时,你会彻底测试它以确保它能给你预期的答案.

SELECT spend,
       SUM(spend) OVER (PARTITION BY user ORDER BY date RANGE BETWEEN 27 * 24 * 60 * 60 * 1000000 PRECEDING AND CURRENT ROW),
       user,
       date
FROM user_spend;
Run Code Online (Sandbox Code Playgroud)

  • 自原始帖子发布以来,文档可能已经发生了变化:```` 提示:如果您想使用日期范围,请将 ORDER BY 与 UNIX_DATE() 函数一起使用。如果要使用带有时间戳的范围,请使用 UNIX_SECONDS()、UNIX_MILLIS() 或 UNIX_MICROS() 函数。``参考:https://cloud.google.com/bigquery/docs/reference/standard-sql/analytic-function-concepts#def_window_frame (3认同)

小智 15

Bigquery:如何在窗口子句中获取滚动时间范围.....

这是一个旧帖子,但我花了很长时间寻找解决方案,这篇帖子出现了,所以也许这会对某人有所帮助。

如果您的 window 子句的分区没有每天的记录,则需要使用 RANGE 子句来准确获取滚动时间范围,(ROWS 会搜索数字记录,因为您没有,这会回溯太远)在您的 PARTITION BY 中没有每天的记录)。问题是在 Bigquery RANGE 子句中不支持日期。

来自 BigQuery 的文档:

numeric_expression 必须具有数字类型。当前不支持 DATE 和 TIMESTAMP。此外,numeric_expression 必须是常量、非负整数或参数。

我发现的解决方法是在 ORDER BY 子句中使用 UNIX_DATE(date_expression) 以及 RANGE 子句:

SUM(value) OVER (PARTITION BY Column1 ORDER BY UNIX_DATE(Date) RANGE BETWEEN 5 PRECEDING AND CURRENT ROW