使用SQL查询用户id、开始和结束会话的时间(如果我们只知道用户id、执行的操作和访问时间)

使用SQL查询用户id、开始和结束会话的时间(如果我们只知道用户id、执行的操作和访问时间),sql,amazon-redshift,Sql,Amazon Redshift,我的任务是打开试用集群Redshift并从csv文件上传数据 在csv文件中,提供了有关用户id、他访问过的页面以及访问时间(毫秒)的信息 任务是查找用户已按给定顺序执行下一步操作的所有会话:rooms.homography-showcase、rooms.view.step.content、rooms.lesson.rev.step.content。他不可能成功地做到这一点 会话是指操作之间的时间间隔不超过一小时 输出应包括用户id、会话开始时间和会话结束时间 csv中给出的示例: 57529,

我的任务是打开试用集群Redshift并从csv文件上传数据

在csv文件中,提供了有关用户id、他访问过的页面以及访问时间(毫秒)的信息

任务是查找用户已按给定顺序执行下一步操作的所有会话:rooms.homography-showcase、rooms.view.step.content、rooms.lesson.rev.step.content。他不可能成功地做到这一点

会话是指操作之间的时间间隔不超过一小时

输出应包括用户id、会话开始时间和会话结束时间

csv中给出的示例:

57529,rooms.homework-showcase,2017-03-01T00:00:07.710000
57529,rooms.view.step.content,2017-03-01T00:00:10.275000
57529,rooms.view.step.content,2017-03-01T00:00:10.436000
168671,rooms.view.step.content,2017-03-01T00:00:12.035000
168671,rooms.view.step.content,2017-03-01T00:00:50.632000
64788,rooms.view.step.content,2017-03-01T00:01:21.460000
93698,rooms.view.step.content,2017-03-01T00:02:41.963000
205265,rooms.homework-showcase,2017-03-01T00:02:45.241000
205265,rooms.test-showcase,2017-03-01T00:02:57.854000
205265,notes,2017-03-01T00:03:01.016000
到目前为止,我写的是:

我可以计算会话的开始和结束,但我不知道如何将最后一行作为会话的结束。一个用户可以有多个会话

如何查询正确的会话并从中获取用户id、会话的开始和结束?你能给我一些想法吗?我没有足够的SQL知识来理解如何编写正确的查询

另外,我已经附上了输出的外观。这显示了特定的用户和他在给定条件下的一个会话。预期输出是最后一张图片。应该列出所有好的课程

csv文件位于此链接下


DB Fiddle

我已经通过self-join使用下面的代码运行了您提供的示例数据。 代码如下:

从中选择用户标识、会话开始、最大会话结束作为会话结束

选择用户标识、会话开始、会话结束为空时的大小写,然后选择会话开始其他会话结束作为会话结束

选择a.user\u id作为用户id,a.datevisted,a.date\u time作为会话开始,a.session\u hour,case when b.date\u time>a.date\u time和a.session\u hour>=b.date\u time然后b.date\u time否则null结束作为会话结束

从a页中选择用户id、truncdate时间作为datevisited、date时间、dateaddhour、1、date时间Session小时

左连接 从b页中选择用户id、truncdate时间作为datevisited、date时间、dateaddhour、1、date时间Session小时

在a.user\u id=b.user\u id和a.datevisited=b.datevisited上

按1,2,3,4,5分组

分组1,2,3决赛

按1,2分组

在你这边测试一下。对于代码中使用的各种功能,您可以参考红移文档:

select *, 
case
when timepass IS NULL then ncount
when (timepass>=3600) and lag(timepass<3600) over(order by user_id, datet) 
then ncount
else Null
end as startt,

case
when (timepass<3600) and lead(timepass IS NULL) over(order by user_id, 
datet) then ncount
when (timepass<3600) and lead(timepass>=3600) over(order by user_id, datet) 
then ncount

else Null
end as endt

from
(
select *, row_number() OVER(ORDER BY user_id, datet) as ncount, 
case 
when page_name = 'rooms.homework-showcase' then 0 
when page_name = 'rooms.view.step.content' then 1
when page_name = 'rooms.lesson.rev.step.content' then 2
else 3
end as page_order
from
(
select *, EXTRACT(EPOCH from datet) - lag(EXTRACT(EPOCH from datet)) 
over(partition by user_id order by user_id, datet) as timepass from
(
SELECT *, to_timestamp(date_time, 'YYYY-MM-DD HH:MI:SS:US') as datet from 
testtbl
order by date_time asc
) as t1

group by user_id, page_name, date_time, datet
order by user_id, datet asc 
) as t3
) as t4
;