题解 | 计算用户的平均次日留存率

计算用户的平均次日留存率

https://www.nowcoder.com/practice/126083961ae0415fbde061d7ebbde453

附上解析:
SELECT 
    ROUND(COUNT(DISTINCT b.device_id, b.date) / COUNT(DISTINCT a.device_id, a.date), 4) AS avg_ret
FROM (
    SELECT DISTINCT device_id, DATE_FORMAT(date, '%Y-%m-%d') AS date 
    FROM question_practice_detail
) a
LEFT JOIN (
    SELECT DISTINCT device_id, DATE_FORMAT(date, '%Y-%m-%d') AS date 
    FROM question_practice_detail
) b
ON a.device_id = b.device_id 
    AND b.date = DATE_ADD(a.date, INTERVAL 1 DAY);

========
关键步骤详解
1.数据去重处理(子查询a和b)
SELECT DISTINCT device_id, DATE_FORMAT(date, '%Y-%m-%d') AS date 
FROM question_practice_detail
目的:确保每个用户每天只计一次活跃(避免同用户同天刷多题造成的重复计数)
示例数据中:
用户3214在2021-05-09有2条记录 → 去重后计1次
用户6543在2021-08-13有3条记录 → 去重后计1次
2.自连接逻辑:
LEFT JOIN ... ON a.device_id = b.device_id 
    AND b.date = DATE_ADD(a.date, INTERVAL 1 DAY)
a表:所有用户活跃日期(作为"第一天")
b表:所有用户活跃日期(作为可能的"第二天")
连接条件:
同一用户 (a.device_id = b.device_id)
b的日期是a的次日 (b.date = a.date + 1 day)
3.留存率计算
ROUND(COUNT(DISTINCT b.device_id, b.date) / COUNT(DISTINCT a.device_id, a.date), 4)
分子:次日仍活跃的用户数(满足连接条件的b表记录数)
分母:总活跃事件数(a表所有记录)
公式:留存率 = 次日活跃用户数 / 当日活跃用户数
============================
特殊处理说明
日期格式标准化:
DATE_FORMAT(date, '%Y-%m-%d') -- 确保时间部分不影响日期比较
跨月/年末处理:
DATE_ADD(a.date, INTERVAL 1 DAY) -- 自动处理月末(如2021-02-28→2021-03-01)
四舍五入:
ROUND(..., 4) -- 保留4位小数,符合示例输出要求

全部评论

相关推荐

点赞 评论 收藏
分享
10-29 19:45
吉林大学 Java
从零开始数:自我评价没有必要写,但是看起来你应该是学了csdiy的一些课程,可以在专业技能里面写上自己比较熟悉操作系统和计网,但如果你是找Java的话,把第一个项目换了吧,现在看起来有点四不像。 无论是黑马点评或者说做个轮子项目,刷题和八股也搞起来吧,而且也没必要等到寒假,最近就可以开始找,找到就偷偷实习呗,别被逮到就行了。
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

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