大数据面试题:用 SQL 查询每个用户最大连续登录日期

前言: “用 SQL 查询每个用户最大连续登录日期?” 这道题是数据开发面试经常问到的题目,因为其比较考验候选人的 SQL 能力,今天就来简单讲讲其思路。

样例数据如下 login_log:

user_id login_time
1 2022-11-28
1 2022-12-01
1 2022-12-02
1 2022-12-03
2 2022-12-01
2 2022-12-04

(1) 先开窗,排个序

不了解或不熟悉窗口函数的同学可以点击阅读:通俗易懂:窗口函数 | 全是案例

select user_id, login_time,
row_number() over(partition by user_id order by login_time) num 
from login_log;

开完窗的结果如下:

user_id login_time num
1 2022-11-28 1
1 2022-12-01 2
1 2022-12-02 3
1 2022-12-03 4
2 2022-12-01 1
2 2022-12-04 2

(2) 利用等差数列的特性

如果是连续登录,login_time - num 则相等,因此可以这样写:

select t.user_id, 
	t.login_time, 
	date_sub(login_time, INTERVAL t.num DAY) date_rslt
from 
(
	select user_id, login_time, 
	row_number() over(partition by user_id order by login_time) num 
	from login_log
) t;

注:INTERVAL 关键字可以用于计算时间间隔, date_sub(login_time, INTERVAL t.num DAY)表示登录时间减去 num 天; 若 DAY 改成 HOUR 表示减去 num 小时。

以上 SQL 执行后得到:

user_id login_time date_rslt
1 2022-11-28 2022-11-27
1 2022-12-01 2022-11-29
1 2022-12-02 2022-11-29
1 2022-12-03 2022-11-29
2 2022-12-01 2022-11-30
2 2022-12-04 2022-12-02

(3)分组后可获得结果:

select a.user_id,
	a.date_rslt,
	count(1) as cnt
from(
	select 
		t.user_id, 
		t.login_time,
		date_sub(login_time, INTERVAL t.num DAY) date_rslt
	from 
		(
		select user_id, 
		login_time, 
		row_number() over(partition by user_id order by login_time) num 
		from login_log
		) t
) a
group by a.user_id, a.date_rslt; 

以上就是全部内容啦,想学习更多大数据相关知识,关注大数据的奇妙冒险。 点赞关注不迷路,转载请注明出处。

#数据人的面试交流地##数据开发工程师##sql##SQL面试##数据仓库工程师#
大数据从入门到放弃 文章被收录于专栏

写点大数据相关的内容,一起交流进步

全部评论
请问这个真的可以实现每个用户的最大连续登录吗,我看了您的代码,感觉只能输出用户的连续登录天数吧……
点赞 回复
分享
发布于 2023-01-05 11:57 江西
学到了,感谢
点赞 回复
分享
发布于 01-23 16:59 广东
滴滴
校招火热招聘中
官网直投

相关推荐

#数据人的面试交流地##数据人##SQL面试#**均为社区同学面试遇到题目**题目:找出连续登录5天的用户图1为模拟数据图2为运行结果Hsql解法如下selectuid,curr,5_dayfrom (        select                 uid,                to_date(`login_date`) curr, --当前日期                last_value(to_date(`login_date`))                         over(partition by uid order by to_date(`login_date`) asc                                 rows BETWEEN  CURRENT ROW and 4 FOLLOWING) as 5_day, -- 当前日期后四天的日期值                DATEDIFF(                last_value(to_date(`login_date`))                         over(partition by uid order by to_date(`login_date`) asc                                 rows BETWEEN  CURRENT ROW and 4 FOLLOWING),                to_date(`login_date`)) AS DRFF_DAY -- 当前日期后四天的日期值 - --当前日期 = 最近五次登录的间隔天数,间隔4才是连续登录5天        from                  (select distinct * from tmp) t1 --一个用户一天可能登录多次,只保留一次) t1 where DRFF_DAY == 4#数据人的面试交流地#更多实战题目及解法思路都在社区!
点赞 评论 收藏
转发
头像
不愿透露姓名的神秘牛友
04-12 16:59
已编辑
1 本科985
点赞 评论 收藏
转发
8 20 评论
分享
牛客网
牛客企业服务