题解 | #2021年11月每天新用户的次日留存率# 详细流程

2021年11月每天新用户的次日留存率

http://www.nowcoder.com/practice/1fc0e75f07434ef5ba4f1fb2aa83a450

流程:

  1. 先查询出每个用户第一次登陆时间(最小登陆时间)--每天新用户表
  2. 因为涉及到跨天活跃,所以要进行并集操作,将登录时间和登出时间取并集,这里union会去重--用户活跃表
  3. 将每天新用户表和用户活跃表左连接,只有是同一用户并且该用户第2天依旧登陆才会保留整个记录,否则右表记录为空
  4. 得到每天新用户第二天是否登陆表后,开始计算每天的次日留存率:根据日期分组计算,次日活跃用户个数/当天新用户个数
select t1.dt,round(count(t2.uid)/count(t1.uid),2) uv_rate
from (select uid
      ,min(date(in_time)) dt
      from tb_user_log 
      group by uid) as t1  -- 每天新用户表
left join (select uid , date(in_time) dt
           from tb_user_log
           union
           select uid , date(out_time)
           from tb_user_log) as t2 -- 用户活跃表
on t1.uid=t2.uid
and t1.dt=date_sub(t2.dt,INTERVAL 1 day)
where date_format(t1.dt,'%Y-%m') = '2021-11'
group by t1.dt
order by t1.dt
全部评论
请问t1.dt=date_sub(t2.dt,INTERVAL 1 day)前面为什么要用and连接,而不用where呢?
1 回复 分享
发布于 2022-04-09 20:39
这个题怎么做都做不出来,是不是没救了。。。心好累
7 回复 分享
发布于 2022-07-16 20:55
想了半天就是没想到union。。。。
4 回复 分享
发布于 2022-07-06 01:01
个人愚见,你这个不严谨,虽然你的代码可能是提交不报错的。假如1号有两个新用户分别是user1和user2,然后user1在次日登录两次,user2没有登录,按理说留存率应该是50%,但是你这个sql将会是66.7%。只是这道题里面的数据恰好没有这种情况罢了。我的做法是先根据uid和dt进行一次分组,算出count(t2.uid),这个值如果是0则表示这个人没有留存,其余的人留存,然后再根据dt分组。
2 回复 分享
发布于 2023-03-07 20:03 广东
t2.uid为啥不用去重?
2 回复 分享
发布于 2022-10-20 15:18 北京
我思路和你差不多,我只考虑了in_time-进入时间,但是in_time-进入时间和out_time-离开时间跨天这个条件我想不出来怎么处理。诶,学艺不精
2 回复 分享
发布于 2022-10-18 15:54 广东
如果用户第1天登录,第3天退出,这次日留存统计不到了
2 回复 分享
发布于 2022-10-14 12:24 湖北
感觉不对吧,如果登陆时间跨越了了三天,刚好错过了第二天,拆出来的数据没有第二天,那结果不是错了?
1 回复 分享
发布于 2024-01-12 17:55 北京
为什么where date_format(t1.dt,'%Y-%m') = '2021-11' 放在最后就可以,但放在每天新用户表里就不行呢。。
1 回复 分享
发布于 2022-05-15 16:36
DATE_SUB() 函数从日期减去指定的时间间隔
1 回复 分享
发布于 2022-01-18 22:13
请问这块去重数据为什莫用distinct不行
点赞 回复 分享
发布于 02-23 17:48 辽宁
执行报错,麻烦大神们看一下什么问题,感谢 select t1.dt, round(count(distinct t2.uid)/count(t1.uid), 2) uv_left_rate from -- 新用户首次登录日期表 (select uid, min(date(in_time)) dt from tb_user_log group by uid) as t1 left join ( select uid, date(in_time) dt from tb_user_log union -- 去重合并获得用户活跃表 select uid, dete(out_time) dt from tb_user_log ) as t2 on t1.uid=t2.uid and t1.dt=date_sub(t2.dt, interval 1 day) where date_format(t1.dt,'%Y-%m') = '2021-11' group by t1.dt order by t1.dt; 程序异常退出, 请检查代码"是否有数组越界等异常"或者"是否有语法错误" SQL_ERROR_INFO: "execute command denied to user 'root'@'localhost' for routine 'dete'"
点赞 回复 分享
发布于 2024-10-22 10:17 北京
如果连续7天登录啥思路呢?
点赞 回复 分享
发布于 2024-07-17 14:31 上海
中间的连接union这里,既然是为了去重为什么不可以用select distinct uid 呢
点赞 回复 分享
发布于 2024-05-02 22:57 广东
为什么要用union呀
点赞 回复 分享
发布于 2024-05-02 22:52 广东
为啥代码复制进去出不来结果的呀。
点赞 回复 分享
发布于 2024-02-21 10:01 广东
其实应该可以不用union,而在leftjoin的时候直接join原表的out_time
点赞 回复 分享
发布于 2023-10-23 01:07 广东
为什么要用union啊,直接查id,in time,out time为什么不行啊
点赞 回复 分享
发布于 2023-10-21 16:30 北京
为什么新用户表,uid 已经用distinct 去重了还需要group by uid,否则就通不过
点赞 回复 分享
发布于 2023-06-13 20:09 辽宁
我想请教一下,这个代码哪里可以体现这是新用户,当天是第一次登录啊?
点赞 回复 分享
发布于 2023-04-09 15:26 辽宁

相关推荐

昨天 13:12
已编辑
门头沟学院 Java
斯卡蒂味的鱼汤:知道你不会来数马,就不捞你😂最近数马疯狂扩招,招聘要求挺低的,你能力肯定够,应该就是因为太强了,知道你不会来才不捞你
投递腾讯云智研发等公司10个岗位
点赞 评论 收藏
分享
评论
274
28
分享

创作者周榜

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