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

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

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

【解题思路】

若是今天注册的用户明天也活跃,那么用活跃的时间减去1必有一天的日期与注册日期是同一天。

【第一步】获得有新用户注册的日期。

select
    uid
    ,min(in_time) as dt
from tb_user_log
group by uid; 

+-----+---------------------+
| uid | dt                  |
+-----+---------------------+
| 101 | 2021-11-01 10:00:00 |
| 102 | 2021-11-01 10:00:00 |
| 103 | 2021-11-01 10:00:01 |
| 104 | 2021-11-02 10:00:28 |
| 105 | 2021-11-03 11:00:53 |
+-----+---------------------+
5 rows in set (0.02 sec)

【第二步】获得用户活跃的所有日期

----------错误代码-----------------
(select 
    uid
    ,in_time as dt
from tb_user_log)
union 
(select
    uid 
    ,out_time as dt
from tb_user_log);

+-----+---------------------+
| uid | in_time             |
+-----+---------------------+
| 101 | 2021-11-01 10:00:00 |
| 102 | 2021-11-01 10:00:00 |
| 103 | 2021-11-01 10:00:01 |
| 101 | 2021-11-02 10:00:09 |
| 103 | 2021-11-02 10:00:51 |
| 104 | 2021-11-02 10:00:28 |
| 101 | 2021-11-03 11:00:55 |
| 104 | 2021-11-03 11:00:45 |
| 105 | 2021-11-03 11:00:53 |
| 101 | 2021-11-04 11:00:55 |
| 101 | 2021-11-01 10:00:42 |
| 102 | 2021-11-01 10:00:09 |
| 103 | 2021-11-01 10:01:50 |
| 101 | 2021-11-02 10:00:28 |
| 103 | 2021-11-02 10:00:59 |
| 104 | 2021-11-02 10:00:50 |
| 101 | 2021-11-03 11:01:24 |
| 104 | 2021-11-03 11:00:55 |
| 105 | 2021-11-03 11:00:59 |
| 101 | 2021-11-04 11:00:59 |
+-----+---------------------+
20 rows in set (0.03 sec)
--------------------在这里就将数据整理一下格式,否则后面因为时间的原因会出现错误------------------------------------
(select 
    uid
    ,date(in_time) as dt
from tb_user_log)
union 
(select
    uid 
    ,date(out_time) as dt
from tb_user_log);
+-----+------------+
| uid | dt         |
+-----+------------+
| 101 | 2021-11-01 |
| 102 | 2021-11-01 |
| 103 | 2021-11-01 |
| 101 | 2021-11-02 |
| 103 | 2021-11-02 |
| 104 | 2021-11-02 |
| 101 | 2021-11-03 |
| 104 | 2021-11-03 |
| 105 | 2021-11-03 |
| 101 | 2021-11-04 |
+-----+------------+
10 rows in set (0.03 sec)

【第三步】对活跃日期减去1,得到起始日期。

--------错误代码--------
select
    uid
    ,date_sub(dt,interval 1 day) as day_init 
from    
(
(select 
    uid
    ,in_time as dt
from tb_user_log)
union 
(select
    uid 
    ,out_time as dt
from tb_user_log)
) t2   
;
+-----+---------------------+
| uid | day_init            |
+-----+---------------------+
| 101 | 2021-10-31 10:00:00 |
| 102 | 2021-10-31 10:00:00 |
| 103 | 2021-10-31 10:00:01 |
| 101 | 2021-11-01 10:00:09 |
| 103 | 2021-11-01 10:00:51 |
| 104 | 2021-11-01 10:00:28 |
| 101 | 2021-11-02 11:00:55 |
| 104 | 2021-11-02 11:00:45 |
| 105 | 2021-11-02 11:00:53 |
| 101 | 2021-11-03 11:00:55 |
| 101 | 2021-10-31 10:00:42 |
| 102 | 2021-10-31 10:00:09 |
| 103 | 2021-10-31 10:01:50 |
| 101 | 2021-11-01 10:00:28 |
| 103 | 2021-11-01 10:00:59 |
| 104 | 2021-11-01 10:00:50 |
| 101 | 2021-11-02 11:01:24 |
| 104 | 2021-11-02 11:00:55 |
| 105 | 2021-11-02 11:00:59 |
| 101 | 2021-11-03 11:00:59 |
+-----+---------------------+
20 rows in set (0.03 sec)


-----------------------
select
    uid
    ,date_sub(dt,interval 1 day) as day_init 
from    
(
(select 
    uid
    ,date(in_time) as dt
from tb_user_log)
union 
(select
    uid 
    ,date(out_time) as dt
from tb_user_log)
) t2   
;
+-----+------------+
| uid | day_init   |
+-----+------------+
| 101 | 2021-10-31 |
| 102 | 2021-10-31 |
| 103 | 2021-10-31 |
| 101 | 2021-11-01 |
| 103 | 2021-11-01 |
| 104 | 2021-11-01 |
| 101 | 2021-11-02 |
| 104 | 2021-11-02 |
| 105 | 2021-11-02 |
| 101 | 2021-11-03 |
+-----+------------+
10 rows in set (0.00 sec)

【第四步】与每日新增用户表连接统计结果即可。

select
    date(a.dt)
    ,round(ifnull(count(b.day_init)/count(a.uid),0),2) as uv_rate
from    
    (select
        uid
        ,date(min(in_time)) as dt
    from tb_user_log
    group by uid) a
left join 
    (select
        uid
        ,date_sub(dt,interval 1 day) as day_init 
    from    
    ( (select 
            uid
            ,date(in_time) as dt
        from tb_user_log)
        union 
        (select
            uid 
            ,date(out_time) as dt
        from tb_user_log
        )
    ) t2
    ) b
on a.uid = b.uid and a.dt = b.day_init
where date_format(a.dt,'%Y-%m')='2021-11' 
group by date(a.dt)
order by date(a.dt);

#SQL练习记录#
全部评论

相关推荐

2024-11-29 11:43
河南科技大学 Java
铁锈不腻玩家:下面那个袁先生删了,问他怎么回事,头像都换不明白
点赞 评论 收藏
分享
沉淀一会:1.同学你面试评价不错,概率很大,请耐心等待; 2.你的排名比较靠前,不要担心,耐心等待; 3.问题不大,正在审批,不要着急签其他公司,等等我们! 4.预计9月中下旬,安心过节; 5.下周会有结果,请耐心等待下; 6.可能国庆节前后,一有结果我马上通知你; 7.预计10月中旬,再坚持一下; 8.正在走流程,就这两天了; 9.同学,结果我也不知道,你如果查到了也告诉我一声; 10.同学你出线不明朗,建议签其他公司保底! 11.同学你找了哪些公司,我也在找工作。
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务