study
study
发布于 2025-11-01 / 50 阅读
0
0

sql&留存率

一、留存率介绍

以某一段时间首次访问或登录系统的用户人数为分母,在之后的某一段时间内,再次登录/访问系统的用户人数为分子,得出的比例,称为留存率

通常用到的留存率有日留存、周期内留存率、周期留存率,日留存率又分为次日、七日、30日等。周期内留存率分为7天留存率、30天留存率等。周期留存率分为周留存率、月留存率等

下面分别按照这几种留存率的定义,以及一张用户登录日期表,来介绍用sql实现的方法

类型

概念

延伸

日留存率

某天d1首次登录的用户数为分母

在之后的某一天(比如d2)再次登录的用户数为分子,得出的百分比

次日、7日、30日

周期留存率

在某个周期(比如d1-d7这一周内)首次登录的用户数为分母

在之后的某个周期(比如d15~d21这一周内)再次登录的用户数为分子

得出的百分比

周留存率

月留存率

周期内留存率

某天d1首次登录的用户数为分母

在之后某段周期内再次登录过的用户数为分子,得出的百分比

7天内留存率

30天内留存率

表名:login_logs

sql文件:login_logs.sql

示例数据:

user_id

login_date

1001

2025-04-01

1002

2025-04-02

1003

2025-04-08

1002

2025-04-09

留存率grafana.jpg

二、日留存率

1、次日留存率

以某一天d1首次访问或登录系统的用户人数为分母,在第二天d2中,再次登录系统的用户人数为分子,得出的比例,称为d1的次日留存率

1.1、获取2025年4月1日的次日留存率

步骤1:获取2025年4月1日首次登录的用户

步骤2:获取2025年4月2日登录的用户

步骤3:关联两份数据,得出4月1日的次日留存率

  # 获取第2025年4月1日首次登录的用户
  with user_first_login as
  (
    select user_id,min(login_date) login_date from login_logs group by user_id
    having min(login_date) = '2025-04-01' 
  ),
  # 获取到2025年4月2日登录的用户
  second_login as
  (
    select * from login_logs where login_date = '2025-04-02'
  )
  
  # 关联两份数据,得出4月1日的次日留存率
  select u.login_date,count(u.user_id) as first_login_number,count(s.user_id) as second_login_number,
    round(100*count(s.user_id) /count(u.user_id),2) as retention_ratio
    from user_first_login u 
    left join second_login s
    on u.user_id = s.user_id group by u.login_date

1.2、获取2025年4月1日到4月10日的次日留存率

步骤1:获取2025年4月1日到4月10日首次登录的用户

步骤2:获取2025年4月2日到4月11日登录的用户

步骤3:关联两份数据,得出4月1日到4月10日的次日留存率

  # 获取在2025年4月1日到4月10日首次登录的用户
  with user_first_login as
  (
    select user_id,min(login_date) as login_date from login_logs group by user_id
    having min(login_date) between '2025-04-01' and '2025-04-10'
  ),
  # 获取到2025年4月2日到4月11日登录过的用户
  second_login as
  (
    select * from login_logs where login_date between '2025-04-02' and '2025-04-11'
  )
  
  # 关联两份数据,得出4月1日到4月10日的次日留存率
  select u.login_date,count(u.user_id) as fisrt_login_number,count(s.user_id) as second_login_number,
    round(100*count(s.user_id) /count(u.user_id),2) as retention_ratio,
    json_arrayagg(u.user_id) as first_login_user,json_arrayagg(s.user_id) as second_login_user
    from user_first_login u 
    left join second_login s
    on u.user_id = s.user_id
    and s.login_date = DATE_ADD(u.login_date,INTERVAL 1 DAY) 
    group by u.login_date

2、7日留存率

以某一天d1首次访问或登录系统的用户人数为分母,在第7天d7中,再次登录系统的用户人数为分子,得出的比例,称为d1的七日留存率

2.1、获取2025年4月1日到4月3日的七日留存率

与次日留存率主要的区别就是对比的日期从d1 vs d2改成了d1 vs d7,sql改动很小

步骤1:获取2025年4月1日到4月3日首次登录的用户

步骤2:获取2025年4月7日到4月9日登录的用户(分别对应1~3号的第7天)

步骤3:关联两份数据,得出4月1日到4月3日的七日留存率

  # 获取在2025年4月1日到4月3日首次登录的用户
  with user_first_login as
  (
    select user_id,min(login_date) as login_date from login_logs group by user_id
    having min(login_date) between '2025-04-01' and '2025-04-03'
  ),
  # 获取到2025年4月7日到4月9日登录的用户(分别对应1~3号的第7天)
  second_login as
  (
    select * from login_logs where login_date between '2025-04-07' and '2025-04-09'
  )
  
  # 关联两份数据,得出4月1日到4月3日的七日留存率
  select u.login_date,count(u.user_id) as fisrt_login_number,count(s.user_id) as second_login_number,
    round(100*count(s.user_id) /count(u.user_id),2) as retention_ratio,
    json_arrayagg(u.user_id) as first_login_user,json_arrayagg(s.user_id) as second_login_user
    from user_first_login u 
    left join second_login s
    on u.user_id = s.user_id
    and s.login_date = DATE_ADD(u.login_date,INTERVAL 6 DAY) 
    group by u.login_date

三、周期留存率

以d1~d7首次访问或登录系统的总用户人数为分母,在d8~d14中,再次登录系统的总用户人数为分子,得出的比例,称为d1~d7的周留存率

月留存率同理

1、周留存率

1.1、获取2025年4月1日开始,之后10周范围内,每一周登录用户在下一周的留存率

步骤1:获取2025年4月1日到之后10周(一共70天)范围内,每一周首次登录的用户

步骤2:获取2025年4月8日到之后10周(一共70天)范围内,每周登录的用户(分别对应4月1日之后10周中每一周的下一周)

步骤3:关联两份数据,得出每一周登录用户在下一周的留存率

  # 获取在2025年4月1日到之后69天范围内,每一周首次登录的用户。以及每一周的开始日期和结束日期
  with week_n_login as (
   select 
    t.*,
    floor((UNIX_TIMESTAMP(t.login_date) - UNIX_TIMESTAMP('2025-04-01'))/(24*3600*7))+1 as week,
    DATE_ADD('2025-04-01',INTERVAL 7*FLOOR((UNIX_TIMESTAMP(login_date) - UNIX_TIMESTAMP('2025-04-01'))/(24*3600*7)) DAY) as   begin_time,
    DATE_ADD('2025-04-01',INTERVAL 7*(1+FLOOR((UNIX_TIMESTAMP(login_date) - UNIX_TIMESTAMP('2025-04-01'))/(24*3600*7)))-1 DAY) as end_time
   from 
  (
  	select user_id,min(login_date) login_date from login_logs group by user_id having min(login_date) between '2025-04-01'   and DATE_ADD('2025-04-01',INTERVAL 69 DAY)
  	) t
  ),
  # 获取到2025年4月8日到之后10周范围内,每周登录的用户(分别对应4月1日之后10周中每一周的下一周)
  week_n1_login as (
   select distinct user_id,login_date,
     FLOOR((UNIX_TIMESTAMP(login_date) - UNIX_TIMESTAMP('2025-04-01'))/(24*3600*7))+1 as week 
     from login_logs where login_date between '2025-04-08' and  DATE_ADD('2025-04-01',INTERVAL 69 DAY)
  )
  
  # 关联两份数据,得出每一周登录用户在下一周的留存率
  select a.week,count(a.user_id) as basic_num,count(b.user_id) as second_week_num,
    round(100*count(b.user_id)/count(a.user_id),2) as week_ratio,any_value(begin_time) begin,any_value(end_time) end_time
    from day_n_login a left join day_n1_login  b on a.user_id = b.user_id and a.week = b.week-1 group by a.week

2、月留存率

以m1(某一个月)首次访问或登录系统的总用户人数为分母,在m2(第2个月,或者后续某个月)中,再次登录系统的总用户人数为分子,得出的比例,称为m1的月留存率

2.1、获取2025年4月、5月的次月留存率

步骤1:获取2025年分别在4月和5月首次登录的用户

步骤2:获取2025年5月和6月登录的用户

步骤3:关联两份数据,得出2025年4月、5月的次月留存率

  # 获取在2025年4月和5月分别首次登录的用户
  with user_first_login AS
  (
    select user_id,DATE_FORMAT(min(login_date),'%Y-%m') as login_month from login_logs group by user_id 
    having min(login_date) between '2025-04-01' and LAST_DAY('2025-05-01')
  ),
  # 获取到2025年5月和6月登录的用户
  second_login as
  (
    select distinct user_id,DATE_FORMAT(login_date,'%Y-%m') as login_month from login_logs
    where login_date between '2025-05-01' and LAST_DAY('2025-06-01')
  )
  
  # 关联两份数据,得出2025年4月、5月的次月留存率
  select u.login_month,count(u.user_id) as first_login_number,count(s.user_id) as second_login_number,
    round(100 * count(s.user_id) / count(u.user_id),2) as retention_ratio
    from user_first_login u left join second_login s on u.user_id = s.user_id
    and s.login_month = DATE_FORMAT(DATE_ADD(concat(u.login_month,'-01'),INTERVAL 1 MONTH),"%Y-%m")
    group by u.login_month


评论