字节跳动面试SQL-用户登录区间合并

推荐阅读文章列表

大数据开发面经汇总【持续更新...】

我的大数据学习之路

大数据开发面试笔记V6.0

SQL题目

来自字节跳动数据研发二面

  • 有一张用户行为日志表ods_usr_log, 包含user_id(用户id)、start_time(登录时间)以及end_time(注销时间)
  • 问题:求出用户登录的所有最大时间段,比如用户1在10:00登录且11点注销,用户2在10:30登录且12:00注销,那么最大时间段就是 10:00到12:00

答案解析

模拟数据

insert into ods_usr_log(user_id, start_time, end_time) values 
(1, '09:01', '10:30'),
(2, '08:10', '09:08'),
(3, '10:20', '11:00'),
(4, '12:00', '13:00'),
(5, '11:30', '11:59')

思路分析

难点:如何对交叉区间进行合并

  1. 按照登录时间和注销时间进行排序
  2. 如果登陆时间小于上一条记录的注销时间,就表示有交叉,打上标签flag=1
  3. 当flag由0变为1的时候,就表示多了一个分组,因此我们可以对flag进行累加,累加后的值即为分组id

具体代码

select 
     group_id
     ,min(start_time) as start_time
     ,max(end_time)   as end_time
from (
         select 
              start_time
              ,end_time
              ,sum(flag) over (order by start_time, end_time) as group_id
         from (
               select 
                    start_time
                    ,end_time
                    ,case when start_time <= lst_end_time then 0 else 1 end as flag
               from (
                         select 
                              start_time
                              ,end_time
                              ,lag(end_time, 1, end_time) over (order by start_time asc, end_time asc) as lst_end_time
                         from ods_user_log
                    ) t
              ) t
     ) t
group by group_id
;
#数据人的面试交流地##校招过来人的经验分享#
全部评论
如果有一个用户的登陆时间很早,退出时间很晚,这个算法就很容易出问题吧
点赞 回复 分享
发布于 07-24 16:28 上海
如果登陆时间小于上一条记录的注销时间,就表示有交叉,打上标签flag=1 这里写错了,打上flag=0
点赞 回复 分享
发布于 07-28 22:00 四川

相关推荐

9 26 评论
分享
牛客网
牛客企业服务