类型一
有一张用户签到表【t_user_attendence】,标记每天用户是否签到(说明:该表包含所有用户所有工作日的出勤记录) ,包含三个字段:
• 日期【fdate】
• 用户id【fuser_id】
• 用户当天是否签到【fis_sign_in:0否1是】
问题1:
请计算截至当前每个用户已经连续签到的天数(输出表仅包含当天签到所有用户,计算其连续签到天数)
输出表【t_user_consecutive_days】:
• 用户id【fuser_id】
• 用户连续签到天数【fconsecutive_days】
解答逻辑:1.最近的一次未签到的日期 2.今天的日期-最近一次未签到日期。
select fuser_id, datediff('2020-12-11',max_fdate) as fconsecutive_days
from t_user_attendence t1
join (
select fuser_id, max(fdate) as max_fdate
from t_user_attendence
where fis_sign_in = 0
group by fuser_id
) as t2 #最近一次未签到日期
on t1.fuser_id = t2.fuser_id
where t1.fdate = '2020-12-11' and t1.fis_sign_in = 1 #今天签到的用户
问题2:
请计算每个用户历史以来最大的连续签到天数(输出表为用户签到表中所有出现过的用户,计算其历史最大连续签到天数)
输出表【t_user_max_days】:
• 用户id【fuser_id】
• 用户最大连续签到天数【fmax_days】
1.计算每次的连续签到次数(1.所有未签到的天数 2.lag未签到日期 3. 日期相减-1)
2.排序 最大值
select fuser_id, ifnull(datediff(fdate,pdate),0) as consective_days
from (
select fuser_id, fdate, lag(fdate) over (partition by fuser_id ordre by fdate) as pdate
from (
select fuser_id, fdate
from t_user_attendence
where fis_sign_in = 0
) as no_sign_in_date
) as lag_date
group by fuser_id
having consective_days = max(consective_days)
order by consective_days desc;
类型二
练习1 计算连续登陆天数 关键词 row_number
百度数据部门的面试题,主要考察row_number
题目:SQL语句如何查询各个用户最长的连续登陆天数?如图左边是源表User,右边是需要达到的查询结果。
作者:李明轩Matthew
链接:https://www.jianshu.com/p/77597eadd3cc
思路1:登陆日期是连续值,通过datediff(curdate(),loadtime)-row_number()over(partition by uid order by loadtime desc)
判断连续的核心是row_number
因为row_number是连续的
所以day-row_number,如果值是恒定的,说明也是连续的,反之一定会变化
select uid,max(active_days)
from (
select uid,cnt,count(*) as active_days
from (
select uid,
datediff(curdate(),loadtime)-row_number()over(partition by uid order by loadtime desc) as cnt
from users
) as t1
group by uid,cnt
) as t2
group by uid