跳到主要内容

网易大数据面试SQL-游戏玩家留存率

⚠️ 待修正

一、题目背景

这道题来自网易的数据分析岗面试。网易是游戏和音乐,数据分析师需要从海量业务数据中挖掘洞见。

业务场景:用户粘性相关需求在日常工作中频繁出现,这类型的SQL题是面试高频考点。

一、题目

现有一张玩家登录日志表 t1_player_login,记录了每个玩家每天的登录情况。请计算每日新增用户的次日留存率、3日留存率和7日留存率。

说明:

  • 次日留存率 = 某日新增用户中第二天仍登录的用户数 / 该日新增用户数
  • 3日留存率 = 某日新增用户中第3天仍登录的用户数 / 该日新增用户数

玩家登录表 t1_player_login:

+-----------+------------+
| player_id | login_date |
+-----------+------------+
| P001 | 2024-01-01 |
| P002 | 2024-01-01 |
| P003 | 2024-01-01 |
| P001 | 2024-01-02 |
| P002 | 2024-01-02 |
| P004 | 2024-01-02 |
| P003 | 2024-01-03 |
| P001 | 2024-01-03 |
| P004 | 2024-01-03 |
| P002 | 2024-01-04 |
| P005 | 2024-01-04 |
| P001 | 2024-01-07 |
| P003 | 2024-01-08 |
+-----------+------------+

三、思路分析

本题考察留存率计算,需要先找出每个用户的首次登录日期(即新增日期),再与后续登录记录进行关联。

解题步骤

  1. 对每个玩家按 login_date 取最小值作为 first_login_date(新增日期);
  2. 将新增表与登录明细表 LEFT JOIN,关联条件为 player_id 相同,且登录日期与首次登录日期的差值为 1、3、7 天;
  3. 按新增日期分组,统计新增用户数和各留存天数对应的留存用户数;
  4. 计算留存率。
维度评分
题目难度⭐️⭐️⭐️
题目清晰度⭐️⭐️⭐️⭐️
业务常见度⭐️⭐️⭐️⭐️⭐️

四、逐步推导

1. 找出每个玩家的首次登录日期

执行SQL

select player_id,
min(login_date) as first_login_date
from t1_player_login
group by player_id

执行结果

+-----------+------------------+
| player_id | first_login_date |
+-----------+------------------+
| P001 | 2024-01-01 |
| P002 | 2024-01-01 |
| P003 | 2024-01-01 |
| P004 | 2024-01-02 |
| P005 | 2024-01-04 |
+-----------+------------------+

2. 计算留存率

执行SQL

select t1.first_login_date,
count(distinct t1.player_id) as new_users,
count(distinct t2.player_id) as day1_retained,
count(distinct t3.player_id) as day3_retained,
count(distinct t4.player_id) as day7_retained,
round(count(distinct t2.player_id) / count(distinct t1.player_id), 4) as day1_rate,
round(count(distinct t3.player_id) / count(distinct t1.player_id), 4) as day3_rate,
round(count(distinct t4.player_id) / count(distinct t1.player_id), 4) as day7_rate
from (select player_id, min(login_date) as first_login_date
from t1_player_login group by player_id) t1
left join t1_player_login t2
on t1.player_id = t2.player_id
and datediff(t2.login_date, t1.first_login_date) = 1
left join t1_player_login t3
on t1.player_id = t3.player_id
and datediff(t3.login_date, t1.first_login_date) = 2
left join t1_player_login t4
on t1.player_id = t4.player_id
and datediff(t4.login_date, t1.first_login_date) = 6
group by t1.first_login_date
order by t1.first_login_date

执行结果

+------------------+-----------+---------------+----------------+----------------+------------+------------+------------+
| first_login_date | new_users | day1_retained | day3_retained | day7_retained | day1_rate | day3_rate | day7_rate |
+------------------+-----------+---------------+----------------+----------------+------------+------------+------------+
| 2024-01-01 | 3 | 2 | 2 | 1 | 0.6667 | 0.6667 | 0.3333 |
| 2024-01-02 | 1 | 1 | 0 | 0 | 1.0000 | 0.0000 | 0.0000 |
| 2024-01-04 | 1 | 0 | 0 | 0 | 0.0000 | 0.0000 | 0.0000 |
+------------------+-----------+---------------+----------------+----------------+------------+------------+------------+

五、常见坑点

坑1:最近日期的新用户无法计算留存 — 最后一天新增用户尚未有"次日",留存率=0/NULL,实际应用需排除最近N天。

坑2:LEFT JOIN条件不完整导致虚高 — 必须同时匹配 user_id 和 date,只匹配 user_id 会把隔天也算成次日留存。

六、举一反三

  1. 3日/7日/30日留存:DATE_ADD偏移量从1改为3/7/30,一次算出多窗口留存

  2. 按渠道计算留存质量:GROUP BY加channel字段,对比不同获客渠道的用户留存

  3. 留存曲线:对每个首次登录日在后续1-30天分别LEFT JOIN,画出完整留存衰减趋势

七、知识点总结

考点说明
LAG / LEAD获取前/后一行数据,用于环比计算、状态变更检测
多表JOINLEFT JOIN保留主表所有数据,COALESCE处理NULL
GROUP BY + 聚合函数分组聚合是数据分析的基础,配合HAVING筛选分组结果
日期函数DATEDIFF / DATE_ADD / unix_timestamp处理日期运算

八、建表语句和数据插入

点击展开 DDL & DML
-- 建表语句
CREATE TABLE t1_player_login (
player_id string COMMENT '玩家ID',
login_date string COMMENT '登录日期'
) COMMENT '玩家登录日志表';

-- 数据插入
INSERT INTO t1_player_login VALUES
('P001', '2024-01-01'),
('P002', '2024-01-01'),
('P003', '2024-01-01'),
('P001', '2024-01-02'),
('P002', '2024-01-02'),
('P004', '2024-01-02'),
('P003', '2024-01-03'),
('P001', '2024-01-03'),
('P004', '2024-01-03'),
('P002', '2024-01-04'),
('P005', '2024-01-04'),
('P001', '2024-01-07'),
('P003', '2024-01-08');
📱关注公众号

「数据仓库技术」文章同步更新,不错过每一篇干货

微信公众号二维码
💬加群交流

备注「数据仓库技术」加入社群,每日一道大厂SQL真题

交流微信二维码

你可能还想看