SQL/BigQuery 中具有固定持续时间的滑动窗口

Posted

技术标签:

【中文标题】SQL/BigQuery 中具有固定持续时间的滑动窗口【英文标题】:Sliding window with fixed duration in SQL/BigQuery 【发布时间】:2020-02-26 21:33:00 【问题描述】:

我有一个时间序列(userid, timestamp),我想确定会话。

会话在用户级别由 5 分钟的固定窗口定义,该窗口从不在前一个会话中的每个新行开始(窗口持续时间理想情况下取决于给定用户的先前行数,但现在我可以忍受固定的窗口持续时间)例如

WITH sample AS (
  SELECT 0 user_id, TIMESTAMP('2020-01-01T00:00:00Z') timestamp UNION ALL -- new session
  SELECT 1, TIMESTAMP('2020-01-01T00:00:00Z') UNION ALL -- new session
  SELECT 1, TIMESTAMP('2020-01-01T00:04:00Z') UNION ALL
  SELECT 1, TIMESTAMP('2020-01-01T00:06:00Z') UNION ALL -- new session
  SELECT 1, TIMESTAMP('2020-01-01T00:10:00Z') UNION ALL
  SELECT 1, TIMESTAMP('2020-01-01T00:11:00Z') UNION ALL -- new session
  SELECT 1, TIMESTAMP('2020-01-01T01:00:00Z')           -- new session
)
SELECT * 
FROM sample;

我被卡住了,因为在我的推理中,确定一行是否启动新会话取决于前几行的“新会话”列值。

我的目标是 BigQuery,因此理想情况下它应该可以在 BQ 语法中使用。

感谢任何帮助/提示!

【问题讨论】:

【参考方案1】:

我想你想要lag() 和一个累积和:

select s.*,
       sum(case when prev_ts > timestamp_add(timestamp, interval -5 minute)
                then 0 else 1  -- "1" starts a new session
           end) over (partition by user_id order by timestamp) as session_num
from (select s.*,
             lag(timestamp) over (partition by user_id order by timestamp) as prev_ts
      from sample s
     ) s

【讨论】:

感谢您的回答戈登林诺夫!问题在于,这里的会话被延长并且持续时间超过了固定的 5 分钟窗口,因为我们只是在最后 5 分钟内寻找另一行。在示例数据集中,TIMESTAMP('2020-01-01T00:06:00Z') 不应启动新会话。 @marchelbling 。 . .如果会话限制为 5 分钟,那么您将遇到一个非常不同的问题。不幸的是,您需要为此目的遍历数据 - 最接近的 BigQuery 支持递归 CTE。 确实,问题是不同的并且本质上是递归的,这就是为什么它让我陷入困境。我不知道可以编写递归 CTE。我会这样看,谢谢! @marchelbling 。 . . BigQuery 不支持递归 CTE,所以不要太兴奋。它确实提供了带有循环的脚本,这在功能上非常接近。

以上是关于SQL/BigQuery 中具有固定持续时间的滑动窗口的主要内容,如果未能解决你的问题,请参考以下文章

SQL BigQuery - 插入具有不同日期范围的行

github 示例上的 SQL/BigQuery

如何比较标准 SQL(BigQuery)中的两个数组?

创建没有固定第二维的3D numpy.ndarray

QML:在 StackView 中,水平可滑动的视觉效果会持续存在

何时堆内存优先于堆栈内存