我是先学习了这位大神留存率的写法,然后我自己完善了一下。@阿柯@
首先声明一下留存的概念
次日留存:1月1日注册的新用户,在1月2日登陆了app。即登陆日期 - 注册日期 = 1天。3日留存:1月1日注册的新用户,在1月3日登陆了app。即登陆日期 - 注册日期 = 2天。7日留存:1月1日注册的新用户,在1月8日登陆了app。即登陆日期 - 注册日期 = 6天。但是目前不同公司对留存的定义不太一样,所以以具体的规则为准,这里只是为了方便大家理解。
表user_infor,包含user_id(用户ID)和reg_time(注册日期)的字段。
表login_log,包含user_id(用户ID)和login_time(登录时间)
2张表的时间都是datetime类型 YYYY-MM-DD HH:MM:SS
首先在navicate中新建2张表,建表是从大神那里复制过来的。
-- 用户注册表create table user_info(user_id varchar(10) primary key,reg_time datetime);insert into user_info values('u_01','-01-01 09:15:00'),('u_02','-01-01 00:04:00'),('u_03','-01-01 22:16:00'),('u_04','-01-01 20:32:00'),('u_05','-01-01 13:59:00'),('u_06','-01-01 21:28:00'),('u_07','-01-01 14:03:00'),('u_08','-01-01 11:00:00'),('u_09','-01-01 23:57:00'),('u_10','-01-01 04:46:00'),('u_11','-01-02 14:21:00'),('u_12','-01-02 11:15:00'),('u_13','-01-02 07:26:00'),('u_14','-01-02 10:34:00'),('u_15','-01-02 08:22:00'),('u_16','-01-02 14:23:00'),('u_17','-01-03 09:20:00'),('u_18','-01-03 11:21:00'),('u_19','-01-03 12:17:00'),('u_20','-01-03 15:26:00');-- 登陆日志表create table login_log(user_id varchar(10),login_time datetime,primary key(user_id,login_time));insert into login_log values('u_02','-01-02 00:14:00'),('u_10','-01-02 08:32:00'),('u_03','-01-02 09:20:00'),('u_08','-01-02 10:07:00'),('u_04','-01-02 10:29:00'),('u_09','-01-02 11:45:00'),('u_05','-01-02 12:19:00'),('u_01','-01-02 14:29:00'),('u_15','-01-03 00:26:00'),('u_14','-01-03 11:18:00'),('u_11','-01-03 13:18:00'),('u_16','-01-03 14:33:00'),('u_06','-01-04 07:51:00'),('u_18','-01-04 08:11:00'),('u_07','-01-04 09:27:00'),('u_10','-01-04 10:59:00'),('u_20','-01-04 11:51:00'),('u_03','-01-04 12:37:00'),('u_17','-01-04 15:07:00'),('u_08','-01-04 16:35:00'),('u_01','-01-04 19:29:00'),('u_14','-01-05 08:03:00'),('u_12','-01-05 10:27:00'),('u_15','-01-05 16:33:00'),('u_19','-01-06 09:03:00'),('u_20','-01-06 15:26:00'),('u_04','-01-08 11:03:00'),('u_05','-01-08 12:54:00'),('u_06','-01-08 19:22:00'),('u_13','-01-09 10:20:00'),('u_15','-01-09 16:40:00'),('u_18','-01-10 21:34:00');
首先同步一下自己学习后的思路
把user_info的新增用户表作为左表把login_log的登录表作为链接表使用user_id将两个表做连接,这样每个用户第一次注册的记录就可以和用户以后的所有登录数据进行匹配上这样就先形成了一个大表
from user_info left join login_log on user_info.user_id = login_log.user_id
在大表的基础按照用户的注册日期进行分组
group by date(user_info.reg_time)
这样同一天注册的用户被分在同一个组里面了首先对每日新增的用户(左表中)进行计数,由于存在重复的数据所有要去重count(distinct user_info.user_id)
,这样就得到了每天的新增用户数。使用sum(datediff(login_time, reg_time) = 1)
as ‘次日留存用户数’ 来分别求的其他几个纬度的用户留存情况。这里声明一下,为什么用sum()而非count()。sum(条件表达式),如果记录满足条件表达式就加1,统计满足条件的行数。 **COUNT(条件表达式),不管记录是否满足条件表达式,只要非NULL就加1。所以如果用count将计算所有的行数而非指定条件的行数。留存率就是将n日用户留存数量 / 对应日期的新增用户数即可
最后的代码就是,我从大神那里复制来的。
select date(reg_time) dt,count(distinct user_info.user_id) 新增用户数,sum(datediff(login_time,reg_time)=1) 次日留存用户数,sum(datediff(login_time,reg_time)=3) 三日留存用户数,sum(datediff(login_time,reg_time)=7) 七日留存用户数,sum(datediff(login_time,reg_time)=1)/count(distinct user_info.user_id) 次日留存率,sum(datediff(login_time,reg_time)=3)/count(distinct user_info.user_id) 三日留存率,sum(datediff(login_time,reg_time)=7)/count(distinct user_info.user_id) 七日留存率from user_info left join login_log on user_info.user_id=login_log.user_idgroup by date(reg_time);+------------+------------+----------------+----------------+----------------+------------+------------+------------+| dt | 新增用户数 | 次日留存用户数 | 三日留存用户数 | 七日留存用户数 | 次日留存率 | 三日留存率 | 七日留存率 |+------------+------------+----------------+----------------+----------------+------------+------------+------------+| -01-01 | 10 | 8 | 6 | 3 |0.8000 |0.6000 |0.3000 || -01-02 |6 | 4 | 3 | 2 |0.6667 |0.5000 |0.3333 || -01-03 |4 | 3 | 2 | 1 |0.7500 |0.5000 |0.2500 |+------------+------------+----------------+----------------+----------------+------------+------------+------------+
我使用concat()与round()函数进行了简单的加工
concat(round(SUM(DATEDIFF(login_time, reg_time) = 1) / COUNT(DISTINCT user_info.user_id) * 100, 1), '%') AS '次日留存率',concat(round(SUM(DATEDIFF(login_time, reg_time) = 7) / COUNT(DISTINCT user_info.user_id) * 100, 0), '%')AS '三日留存率',concat(round(SUM(DATEDIFF(login_time, reg_time) = 7) / COUNT(DISTINCT user_info.user_id) * 100, 0), '%')AS '7日留存率'
这样就行变为百分数的形式了
如果觉得《mysql 用户留存率计算(每日新增DNU 次日留存率 3日留存率 7日留存率)》对你有帮助,请点赞、收藏,并留下你的观点哦!