Reputation: 524
I have a table that looks like this:
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
I have a query that identifies user sessions, which are action #1, #2 and #3, made in a time period less than one hour from each other. Example of a session:
2 action #1 2017-10-05 15:24
2 action #2 2017-10-05 16:14
2 action #3 2017-10-05 16:34
My query so far looks like this and shows user_id of users, who had sessions:
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
What I need is to edit a query, add 2 columns to the output, session start time and session end time, which is last action + 1 hour. Please advice how to make it. Temporary tables are forbidden, so it should be just a query. Thanks for your time!
Upvotes: 0
Views: 127
Reputation: 37347
Try this:
;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]
Upvotes: 1