首页 > 试题广场 >

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

[编程题]牛客每个人最近的登录日期(三)
  • 热度指数:128358 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
牛客每天有很多人登录,请你统计一下牛客新登录用户的次日成功的留存率,
有一个登录(login)记录表,简况如下:
id
user_id client_id
date
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-13
7 1 2 2020-10-14
第1行表示user_id为2的用户在2020-10-12使用了客户端id为1的设备第一次新登录了牛客网
。。。
第4行表示user_id为2的用户在2020-10-12使用了客户端id为2的设备登录了牛客网
。。。
最后1行表示user_id为1的用户在2020-10-14使用了客户端id为2的设备登录了牛客网


请你写出一个sql语句查询新登录用户次日成功的留存率,即第1天登陆之后,第2天再次登陆的概率,保存小数点后面3位(3位之后的四舍五入),上面的例子查询结果如下:
p
0.500
查询结果表明:
user_id为1的用户在2020-10-12第一次新登录了,在2020-10-13又登录了,算是成功的留存
user_id为2的用户在2020-10-12第一次新登录了,在2020-10-13又登录了,算是成功的留存
user_id为3的用户在2020-10-12第一次新登录了,在2020-10-13没登录了,算是失败的留存
user_id为4的用户在2020-10-13第一次新登录了,在2020-10-14没登录了,算是失败的留存
故次日成功的留存率为 2/4=0.5
(sqlite里查找某一天的后一天的用法是:date(yyyy-mm-dd, '+1 day'),四舍五入的函数为round,sqlite 1/2得到的不是0.5,得到的是0,只有1*1.0/2才会得到0.5
mysql里查找某一天的后一天的用法是:DATE_ADD(yyyy-mm-dd,INTERVAL 1 DAY),四舍五入的函数为round)

示例1

输入

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-13'),
(7,1,2,'2020-10-14');

输出

0.500
头像 SunburstRun
发表于 2020-08-20 14:37:20
要统计牛客新登录用户的次日成功的留存率,首先把公式列出来: (第一天登录的新用户并且第二天也登录的用户)/(总用户)即为新登录用户的次日成功的留存率 总用户其实挺好算,如下: select count(distinct user_id) from& 展开全文
头像 高质量搬砖人
发表于 2021-02-01 10:59:27
方法)借鉴大牛的方法,思路清晰、简洁高效,太厉害了 新登录用户的次日成功的留存率解题公式:(第一天登录的新用户并且第二天也登录的用户)/(总用户) 总用户数量select count(distinct user_id) from login 每个用户第一天登陆的日子(即为新用户)select us 展开全文
头像 马小舍
发表于 2020-12-11 14:53:58
题目中要求是 新登录用户 查询用户的user_id和首次登陆日期,确认是新登录用户。 select user_id,min(date) first_date from login group by user_id 次日成功的留存率,即第1天登陆之后,第2天再次登陆的概率 在1中的表后连接第2天的 展开全文
头像 牛客485505005号
发表于 2021-05-20 19:44:46
SELECT round( sum( CASE WHEN date = date_add( d, INTERVAL 1 DAY ) THEN 1 ELSE 0 END )* 1 / sum( CASE WHEN date = d THEN 1 ELSE 0 END 展开全文
头像 烛少
发表于 2022-02-06 22:29:40
本题比较有意思,方法思路非常多 1、巧秒方法:在group_concat(date)中找用户最找登录日期的下一天,如果能找到,那就标记为1,否则为0 select round(sum(t)/count(*),3) from (select user_id ,if( FIND_IN_SET(date 展开全文
头像 qstalking
发表于 2021-01-26 00:10:57
#第一次登录时间 min(date) 后一天 date_add(min(date),interval 1 day) #分母是表里的去重总用户数,分子是(用户id,date)满足次日留存的条件。 select round(t1.c1/count(distinct l.use 展开全文
头像 Vulcan0418
发表于 2021-07-12 16:09:33
select round(count(distinct b.user_id)/count(distinct a.user_id),3) as pfrom (select user_id,min(date) as date from login group by 1) as aleft joinlog 展开全文
头像 牛客624090436号
发表于 2021-07-23 16:23:07
两个表进行关联,判断id相同时,在克隆表的记录里将日期减一时是否有相同记录 如 2 '2020-06-06' 是否有 2 '2020-06-07' 这条记录可以通过减一天与其相匹配 有的话就认为2再次日登录了 因为统计的是新用户,所以进行去重统计即可 (1三天都登陆了,查出来两条符合的记录,但是 展开全文
头像 牛客732226984号
发表于 2021-01-13 22:38:49
留存率公式:留存率 = (第一天且第二天均登录的用户数)/(总的用户数) 第一步:获得总的用户数 select count(distinct user_id) from login第二步:构建新表,在原表的基础上以min(date)为基础构建第二天字段 select user_id, 展开全文
头像 牛客180843026号
发表于 2021-12-27 17:26:39
首先:指出某种思路不正确。 每人的最小日期的次日有登录则记成功,否则失败。(X) 然后:指出正确的思路。 每人的任何日期的次日有登录则记成功,否则失败。(V) select round(COUNT(distinct case when datediff(b.date, a.date) = 展开全文