题解 | #牛客每个人最近的登录日期(三)#

牛客每个人最近的登录日期(三)

http://www.nowcoder.com/practice/16d41af206cd4066a06a3a0aa585ad3d

本题比较有意思,方法思路非常多 1、巧秒方法:在group_concat(date)中找用户最找登录日期的下一天,如果能找到,那就标记为1,否则为0

select round(sum(t)/count(*),3) from 
(select user_id
,if(
FIND_IN_SET(date_add(min(date),interval 1 day),group_concat(date)),1,0
) as t from login
group by user_id) a

2、使用左连接方法,where子句中添加条件左表日期+1天=右表日期

SELECT ROUND(count(r.date) / COUNT(*), 3)
FROM (SELECT user_id, MIN(date) AS date FROM login GROUP BY user_id) l
LEFT JOIN login r ON l.user_id = r.user_id 
AND DATE_ADD(l.date, INTERVAL 1 DAY) = r.date
ORDER BY l.user_id, l.date

3、使用where in判断user_id是否在下一天登录

SELECT
ROUND(
COUNT(DISTINCT user_id)/(SELECT COUNT(DISTINCT user_id) FROM login)
,3)
FROM login
WHERE (user_id, date)
IN
(SELECT user_id, DATE_ADD(MIN(date),INTERVAL 1 DAY) FROM login GROUP BY user_id);

4、使用nth_value()和first_value()窗口函数,注意窗口函数外面不能再套用count或sum函数

select round(sum(date)/count(*),3) p from
(select distinct user_id,
case when
(nth_value(date,2) over w - first_value(date) over w)=1 then 1 else 0 end
as date
from login l
window w as(
partition by user_id order by date asc rows between unbounded preceding and unbounded following
))a

5、使用lead()窗口函数,与方法2思路是一致的

select round(
count(distinct case when datediff(ld,date) = 1 then user_id else null end)
/count(distinct user_id)
,3) as p 
from
(SELECT user_id, date
,lead(date,1)over(partition by user_id order by date)ld
from login )a
全部评论
大神
点赞
送花
回复
分享
发布于 2022-05-02 23:03
感谢大佬
点赞
送花
回复
分享
发布于 2022-11-14 11:32 天津
网易互娱
校招火热招聘中
官网直投
个人感觉第5种方法有些瑕疵,用lead是在查询连续两天都登录了的用户id,那么假设一个用户在第一天为首次登录,第二天没有登录,然后在第三天和第四天连续登录,datediff(date,ld)=1是会将第三天第四天连续登录的这个用户纳入进去的,但实际上此用户首次登录后第二天并没有继续登录,因此并不能纳入首登次日留存
点赞
送花
回复
分享
发布于 2022-11-28 17:53 河南

相关推荐

8 1 评论
分享
牛客网
牛客企业服务