首页 > 试题广场 >

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

[编程题]牛客每个人最近的登录日期(五)
  • 热度指数:182678 时间限制: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 1 2 2020-10-13
6 3 1 2020-10-14
7 4 1 2020-10-14
8 4 1 2020-10-15
第1行表示user_id为2的用户在2020-10-12使用了客户端id为1的设备登录了牛客网,因为是第1次登录,所以是新用户
......
第4行表示user_id为2的用户在2020-10-13使用了客户端id为2的设备登录了牛客网,因为是第2次登录,所以是老用户
......
最后1行表示user_id为4的用户在2020-10-15使用了客户端id为1的设备登录了牛客网,因为是第2次登录,所以是老用户

请你写出一个sql语句查询每个日期新用户的次日留存率,结果保留小数点后面3位数(3位之后的四舍五入),并且查询结果按照日期升序排序,上面的例子查询结果如下:
date
p
2020-10-12
0.667
2020-10-13
0.000
2020-10-14
1.000
2020-10-15
0.000
查询结果表明:
2020-10-12登录了3个(user_id为2,3,1)新用户,2020-10-13,只有2个(id为2,1)登录,故2020-10-12新用户次日留存率为2/3=0.667;
2020-10-13没有新用户登录,输出0.000;
2020-10-14登录了1个(user_id为4)新用户,2020-10-15,user_id为4的用户登录,故2020-10-14新用户次日留存率为1/1=1.000;
2020-10-15没有新用户登录,输出0.000;
(注意:sqlite里查找某一天的后一天的用法是:date(yyyy-mm-dd, '+1 day'),sqlite里1/2得到的不是0.5,得到的是0,只有1*1.0/2才会得到0.5)


示例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,1,2,'2020-10-13'),
(6,3,1,'2020-10-14'),
(7,4,1,'2020-10-14'),
(8,4,1,'2020-10-15');

输出

2020-10-12|0.667
2020-10-13|0.000
2020-10-14|1.000
2020-10-15|0.000
头像 牛客题解官
发表于 2025-03-18 17:48:51
精华题解 这道题目要求我们计算每个日期的新用户次日留存率。我们要做的事情如下: 1. 确定总体问题 我们需要计算每个日期的新用户次日留存率,次日留存率是指在某个日期首次登录的新用户中,有多少用户在次日再次登录。我们需要从登录记录表中提取数据,使用窗口函数ROW_NUMBER来标记每个用户的首次和次次登录日期, 展开全文
头像 牛客792727317号
发表于 2021-05-18 17:51:54
一、确定总体问题 每个日期 新用户 的次日留存 率 -- 关键问题 结果保留小数点后面3位数(3位之后的四舍五入) --次要问题 并且查询结果按照日期升序排序 -- 次要问题 二、分析关键问题(约束条件) 每个日期的新用户数--分母 展开全文
头像 黑猫5454
发表于 2021-04-12 11:51:48
提供一种使用左连接特性的解法,思路十分十分容易懂首先我们想到是查出所有第一次登录的人和他第一次登录的日期 ( select user_id,min(date) as date from login group by user_id )t1然后我们又应该想到的是,我们要看这些人 展开全文
头像 qstalking
发表于 2021-01-26 12:37:40
#明确问题:12号的新用户次留是指在12号是第一次登录,并且在13号也登录了。 #分母:当前日期新用户的特征是 当前日期=该用户所有登录日期的最小值 #分子:当前日期作为前一天有该用户的登录记录 并且是第一次登录。(代码中的-1是把某个用户在整张login表的日期-1,12号作为前一天有这个人, 展开全文
头像 高质量搬砖人
发表于 2021-02-01 11:48:36
发现其他大神的一个很好懂的解法! 求出新用户第一天登录日期SELECT user_id,MIN(date) AS date FROM login GROUP BY user_id 算出有新用户登录的日期的新用户留存率SELECT a.date,ROUND(COUNT(DISTINCT login. 展开全文
头像 SunburstRun
发表于 2020-08-20 15:09:36
这个题目如果你做过牛客每个人最近的登录日期(三)和牛客每个人最近的登录日期(四),那么解决起来会容易很多,做过(四)https://blog.nowcoder.net/n/a2f955514f824bb888f9d7726421e809我们知道每个日期的新用户求法为: select  展开全文
头像 vyydyfubjjjf
发表于 2021-06-06 17:16:43
面试后得到反馈说,因为笔试一直在用子查询跟join虽然对了但不好,所以要加试。在加试之前回来把刷过的题都练习着改一遍,尽量用case when跟窗口函数代替子查询跟join。以下是我的尝试: select date, ifnull(round(sum(case when date=min_date 展开全文
头像 莫迟
发表于 2021-08-09 16:01:00
MySQL窗口函数解法 select date, round(ifnull(lead(sum(next_day),1)over(order by date)/sum(new),0),3) from (select date, if(date=(min(date)over( 展开全文
头像 109号
发表于 2020-12-06 12:33:54
这个题目关键的是找到每天的新用户数和次日的新用户留存数容易忽略的是留存为0的日期 SELECT a.date,ROUND(COUNT(DISTINCT login.user_id)/ COUNT(a.user_id),3) AS p FROM (这个查询是为了找到每天的新用户数 SELECT 展开全文
头像 朝阳1005
发表于 2021-06-19 19:17:08
首先明确概念,当日留存率=明日老用户数/当日新用户数即我们需要分别求老用户数和新用户数就可以。 【新用户数】 根据上一题求解: select distinct date ,sum(case when (user_id,date) in (select user_id,min 展开全文
头像 JezeChou
发表于 2021-06-18 11:30:09
此题应该是目前牛客处理比较复杂的sql题了。 一、审题“写出一个sql语句查询每个日期新用户的次日留存率,结果保留小数点后面3位数(3位之后的四舍五入),并且查询结果按照日期升序排序。”根据题目描述,次日留存率指新用户第二天登录的个数除以新用户第一天登录的个数。 二、解题1、统计新用户第一天登录的次 展开全文

问题信息

SQL
难度:
658条回答 8124浏览

热门推荐

通过挑战的用户

查看代码
牛客每个人最近的登录日期(五)