首页 > 数据库 > 数据库开发技术 > 你能连续读书多少天?

【面试题】
有一张“阅读记录表”,包含2个字段:用户id、阅读日期。

查询3月份以来,连续阅读5天及以上的用户名单。
【解题步骤】
1. 连续问题的万能模板
我在《拼多多面试题:如何找出连续出现N次的内容?》里讲过遇到“连续问题”如何解决,并送出了一个万能模板,模板使用的是窗口函数解决连续问题。
select distinct 列1from(select 列1,lead(列1,1) over(order by 序号) as 列2,lead(列1,2) over(order by 序号) as 列3,...lead(列1,n-1) over(order by 列) as 列n,from 表名) as awhere (a.列1 = a.列2 and ... and a.列1 = a.列n);
2. 窗口函数
窗口函数lead使用方法:
lead(字段名,N,默认值) over(partion by …order by …)默认值是指:当向上N行或者向下N行值时,如果已经超出了表行和列的范围时,会将这个默认值作为函数的返回值,若没有指定默认值,则返回Null。
窗口函数lead可以获取每个字段的后面的第n个值,并生成新的一列。
select *,lead(阅读日期,1) over(partition by 用户id order by 阅读日期) as 后面第1个日期,lead(阅读日期,2) over(partition by 用户id order by 阅读日期) as 后面第2个日期,lead(阅读日期,3) over(partition by 用户id order by 阅读日期) as 后面第3个日期,lead(阅读日期,4) over(partition by 用户id order by 阅读日期) as 后面第4个日期from 阅读记录表where 阅读日期 >= '2021-03-01';
查询结果:

3. 子查询
基于窗口函数lead获取的结果,要筛选出连续阅读5天及以上的用户名单。
只需要满足以下条件:
1)“后面第1个日期”与“阅读日期”差1天;
2)“后面第2个日期”与“阅读日期”差2天;
3)“后面第3个日期”与“阅读日期”差3天;
4)“后面第4个日期”与“阅读日期”差4天。
一个用户同时满足上面4个条件,说明:该用户至少一次连续阅读了5天。
以上条件的过滤可以使用date_sub函数:获取某个日期前n天的日期。
最终结果为:
select distinct 用户idfrom (select *,lead(阅读日期,1) over(partition by 用户id order by 阅读日期) as 后面第1个日期,lead(阅读日期,2) over(partition by 用户id order by 阅读日期) as 后面第2个日期,lead(阅读日期,3) over(partition by 用户id order by 阅读日期) as 后面第3个日期,lead(阅读日期,4) over(partition by 用户id order by 阅读日期) as 后面第4个日期from 阅读记录表where 阅读日期 >= '2021-03-01') as awhere date_sub(后面第1个日期,interval 1 day) = 阅读日期and date_sub(后面第2个日期,interval 2 day) = 阅读日期and date_sub(后面第3个日期,interval 3 day) = 阅读日期and date_sub(后面第4个日期,interval 4 day) = 阅读日期;
查询结果:

【本题考点】
1.考查对窗口函数的了解;
2.考查对子查询的了解;
3.考查对连续问题的了解,可以套用万能模板。

原文作者:猴子数据分析;如有侵权,请联系管理员删除。