SQL_牛客网_SQL264_求每个登陆日期的次日留存率

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

牛客每天有很多人登录,请你统计一下牛客每个日期新用户的次日留存率。
有一个登录(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.构建新用户临时表B

2.判断原表中是否存在与新用户临时表B,datediff()计算日期差值为1的记录,如果有则为新用户次日留存。

with t1 as (
    select user_id, min(date) min_date
    from login
    group by user_id
)
select 
    date,
    round(if(P,P,0),3) P 
from(
    select l1.date 'date', round(sum(if((l1.user_id,l1.date) in (select * from t1) and l2.user_id,1,0))/sum(if((l1.user_id,l1.date) in (select * from t1),1,0)),3) P
    from login l1 left join login l2
        on l1.user_id=l2.user_id and datediff(l2.date,l1.date)=1
    group by l1.date
    order by l1.date
)t2

好的,这是一个统计留存率的问题,留存率的定义是指在某个时间段内,用户继续使用产品的比例。对于这个问题,我们需要计算新登录用户在第二天仍然登录的比例。具体步骤如下: 1. 找到所有新登录用户 新登录用户的定义是第一次登录牛客网的用户,因此我们需要找到第一次登录的记录,可以按日期升序排序,然后按用户分组,取每个用户的第一条记录即可。 2. 计算次日留存率 对于每个新登录用户,找到其第二天的登录记录,如果存在,则认为该用户次日成功留存,否则认为该用户次日未留存。最后将留存用户数除以总登录用户数即可得到留存率。 下面是具体的 SQL 语句实现: ``` SELECT COUNT(DISTINCT t1.user_id) AS login_users, COUNT(DISTINCT t2.user_id) AS retained_users, COUNT(DISTINCT t2.user_id) / COUNT(DISTINCT t1.user_id) AS retention_rate FROM login_records t1 LEFT JOIN login_records t2 ON t1.user_id = t2.user_id AND DATEDIFF(t2.date, t1.date) = 1 WHERE t1.date = (SELECT MIN(date) FROM login_records WHERE user_id = t1.user_id) ``` 解释一下这个 SQL 语句。首先,我们使用左连接将每个新登录用户的记录和其第二天的记录连接起来,连接条件是用户相同且日期相差1天。然后,我们使用 WHERE 子句过滤出每个用户的第一条记录,并计算总登录用户数、留存用户数和留存率。其中,COUNT(DISTINCT t1.user_id) 表示总登录用户数,COUNT(DISTINCT t2.user_id) 表示留存用户数,COUNT(DISTINCT t2.user_id) / COUNT(DISTINCT t1.user_id) 表示留存率。 注意,这里使用了子查询来找到每个用户的第一条记录,具体做法是在 WHERE 子句中使用了一个标量子查询,该子查询返回每个用户的最早登录日期
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值