【问题标题】:Query to find all timestamps more than a certain interval apart查询以查找相隔超过某个间隔的所有时间戳
【发布时间】:2014-10-26 04:10:29
【问题描述】:

我正在使用 postgres 对用户活动进行一些分析。我有一个每个用户发出的所有请求(页面浏览量)的表和请求的时间戳,我试图找到每个用户的不同会话数。为简单起见,我将每组请求与其他请求相隔一个小时或更长时间视为一个不同的会话。数据看起来像这样:

id|          request_time|         user_id
1    2014-01-12 08:57:16.725533    1233
2    2014-01-12 08:57:20.944193    1234
3    2014-01-12 09:15:59.713456    1233
4    2014-01-12 10:58:59.713456    1234

如何编写查询来获取每个用户的会话数?

【问题讨论】:

    标签: sql postgresql aggregate-functions window-functions


    【解决方案1】:

    在每个间隔 >= 1 小时后开始新会话:

    SELECT user_id, count(*) AS distinct_sessions
    FROM (
       SELECT user_id
            ,(lag(request_time, 1, '-infinity') OVER (PARTITION BY user_id
                                                      ORDER BY request_time)
               <= request_time - '1h'::interval) AS step -- start new session
       FROM   tbl
       ) sub
    WHERE  step
    GROUP  BY user_id
    ORDER  BY user_id;
    

    假设request_time NOT NULL

    说明:

    • 在子查询sub 中,检查每一行是否有新会话开始。使用lag() 的第三个参数提供默认的-infinity,它低于任何时间戳,因此总是为第一行启动一个新会话。

    • 在外部查询中计算新会话启动的次数。消除 step = FALSE 并按用户计数。

    另类解释

    如果您真的想计算至少发生一个请求的小时数(我认为您不会这样做,但另一个答案假设如此),您会:

    SELECT user_id
         , count(DISTINCT date_trunc('hour', request_time)) AS hours_with_req
    FROM   tbl
    GROUP  BY 1
    ORDER  BY 1;
    

    【讨论】:

    • 您将如何返回每个岛屿的唯一编号而不是布尔值? (为了找到每个岛内的混合/最大值,或返回会话的持续时间)(在 similar problem 上工作)
    猜你喜欢
    • 2015-05-21
    • 2014-07-12
    • 2014-08-21
    • 2010-10-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多