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

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

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
全部评论
个人感觉第5种方法有些瑕疵,用lead是在查询连续两天都登录了的用户id,那么假设一个用户在第一天为首次登录,第二天没有登录,然后在第三天和第四天连续登录,datediff(date,ld)=1是会将第三天第四天连续登录的这个用户纳入进去的,但实际上此用户首次登录后第二天并没有继续登录,因此并不能纳入首登次日留存
2 回复 分享
发布于 2022-11-28 17:53 河南
和评论区的祖国花朵意见一致,使用lead()窗口函数不严谨,如果用户登录了第一天,第三天,第四天,是不应该被算进次日登录的,而题解会将此情况用户也算进分子,例如以下案例user_id为11的用户,以下情况正确答案应该为0.25(一共4个用户,只有user_id为2的用户次日登录了),而题解算出的结果为0.5 drop table if exists login; CREATE TABLE `login` ( `id` int(4) NOT NULL, `user_id` int(4) NOT NULL, `client_id` int(4) NOT NULL, `date` date NOT NULL, PRIMARY KEY (`id`)); INSERT INTO login VALUES (1,2,1,'2020-10-12'), (2,3,2,'2020-10-12'), (3,1,2,'2020-10-12'), (4,2,2,'2020-10-13'), (5,4,1,'2020-10-13'), (6,1,2,'2020-10-14'), (7,1,2,'2020-10-15');
点赞 回复 分享
发布于 2024-08-28 12:45 上海
感谢大佬
点赞 回复 分享
发布于 2022-11-14 11:32 天津
大神
点赞 回复 分享
发布于 2022-05-02 23:03

相关推荐

评论
19
2
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务