【问题标题】:Group values by continuous periods in BigQuery在 BigQuery 中按连续时间段对值进行分组
【发布时间】:2017-02-08 11:27:46
【问题描述】:

考虑一下 BigQuery 表的这种架构:

+---------------------------------------+
|ServiceId |UserId |Date                |
+---------------------------------------+
|s1        |u1     |2016|09|01 00:00:00 |
|s1        |u1     |2016|09|02 00:00:00 |
|s1        |u2     |2016|09|02 12:00:00 |
|s1        |u2     |2016|09|05 00:00:00 |
|s1        |u1     |2016|09|10 12:00:00 |
|s2        |u1     |2016|09|06 00:00:00 |
|s2        |u2     |2016|09|10 00:00:00 |
|s2        |u2     |2016|09|10 12:00:00 |
|s2        |u2     |2016|09|11 12:00:00 |
+---------------------------------------+

它说明了已识别用户对系统某些资源的使用情况。它就像一个活动日志。

我需要一个允许我检索资源随时间的连续使用情况的查询。由于该表不包含“开始”和“结束”日期,因此结束被认为是该期间的最后一个记录日。

如果两个日期相隔最多 24 小时,则认为两个日期是连续的。

这是使用给定表的此类查询的预期输出:

+-------------------------------------------------------------+
|ServiceId  |UserId |StartDate           |EndDate             |
+-------------------------------------------------------------+
|s1         |u1     |2016|09|01 00:00:00 |2016|09|02 00:00:00 |
|s1         |u2     |2016|09|02 12:00:00 |2016|09|02 12:00:00 |
|s1         |u2     |2016|09|05 00:00:00 |2016|09|05 00:00:00 |
|s1         |u1     |2016|09|10 12:00:00 |2016|09|10 12:00:00 |
|s2         |u1     |2016|09|06 00:00:00 |2016|09|06 00:00:00 |
|s2         |u2     |2016|09|10 00:00:00 |2016|09|11 12:00:00 |
+-------------------------------------------------------------+

换句话说:我需要确定用户连续使用服务的时间段。

BigQuery 上的窗口函数文档(herehere)没有此类用例的明确示例(事实上,它们根本没有日期示例)。

如何使用 BigQuery 做到这一点?

谢谢。

【问题讨论】:

    标签: google-bigquery window-functions


    【解决方案1】:

    嗯。 . .我认为它看起来像这样:

    select serviceid, userid, min(date), max(date)
    from (select t.*,
                 sum(case when dateadd(prev_date, 1, "hour") < date then 1 else 0 end) over (partition by serviceid, userid order by date) as grp
          from (select t.*,
                       lag(date) over (partition by serviceid, userid order by date) as prev_date
                from t
               ) t
          ) t
    group by serviceid, userid, grp;
    

    它的作用是识别超过 1 小时的休息时间,并在发生这种情况时分配标志 1。然后它对标志进行累积总和并将其用于聚合。

    【讨论】:

    • 我试过了,它进行了一些调整:prev_date 应该包含在 USEC_TO_TIMESTAMP 函数中(由于 lag 函数和时间戳的错误,更多信息 here ),比较里面的数字应该切换(then 1 else 0)。
    • 标准 SQL 没有这个问题,如果它有帮助的话。 cloud.google.com/bigquery/sql-reference
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多