修改SQL查询以显示用户会话长度

时间:2018-03-08 06:40:31

标签: sql amazon-redshift

我有一个看起来像这样的表:

user_id   user_action      timestamp
1         action #2     2016-02-01 00:02  
2         action #1     2017-10-05 15:24
3         action #3     2017-03-31 19:35
4         action #1     2017-07-09 00:24
1         action #1     2018-11-05 18:28
1         action #3     2018-02-01 13:02
2         action #2     2017-10-05 16:14
2         action #3     2017-10-05 16:34
etc

我有一个查询,用于识别用户会话,即行动#1,#2和#3,在彼此不到一小时的时间段内制作。会话示例:

2         action #1     2017-10-05 15:24
2         action #2     2017-10-05 16:14
2         action #3     2017-10-05 16:34 

到目前为止,我的查询如下所示,并显示了具有会话的用户的user_id:

select distinct user_id
from (select user_id,user_action,timestamp,
      lag(user_action) over(partition by user_id order by timestamp) as prev_action,
      lead(user_action) over(partition by user_id order by timestamp) as next_action,
      datediff(minute,lag(timestamp) over(partition by user_id order by timestamp),timestamp) as time_diff_with_prev_action,
      datediff(minute,timestamp,lead(timestamp) over(partition by user_id order by timestamp)) as time_diff_with_next_action
      from tbl
     ) t
where user_action='action#2' and prev_action='action#1' and next_action='action#3'
and time_diff_with_prev_action <= 60 and time_diff_with_next_action <= 60

我需要的是编辑查询,在输出中添加2列,会话开始时间和会话结束时间,这是最后一次操作+ 1小时。请告知如何制作它。临时表是被禁止的,所以它应该只是一个查询。 谢谢你的时间!

1 个答案:

答案 0 :(得分:1)

试试这个:

;with cte as (
    select [user_id],
           cast(RIGHT([user_action], 1) as int) [action_id],
           [timestamp]
    from @table
),cte2 as (
    select *,
           (select [timestamp] from cte
            where C.[user_id] = [user_id] and C.[action_id] + 1 = [action_id]
              and DATEDIFF(minute, C.[timestamp], [timestamp]) between 0 and 60) [nextActionTimestamp]
    from cte [C]
)

select [user_id],
       [action_id],
       [timestamp] [SessionStart],
       dateadd(hour, 1, [nextNextActionTimestamp]) [SessionEnd]
from (
select *,
       (select [nextActionTimestamp] from cte2
        where C.[user_id] = [user_id] and C.[action_id] + 1 = [action_id]
          and DATEDIFF(minute, C.[nextActionTimestamp], [nextActionTimestamp]) between 0 and 60) [nextNextActionTimestamp]
from cte2 [C]
) a
where [nextActionTimestamp] is not null and [nextNextActionTimestamp] is not null
order by [user_id],[action_id]