会员留存的计算思路

需求

以周为单位,三周为一个跟踪周期来计算每周会员留存率。例如 2018 第 23 周的留存率需要计算出如下的结果:

23周 24 周 25 周
50 个会员 23 个会员 24 个会员

方法1

利用子查询的方式来计算每周的留存率。类似下面的 sql

select 'week1' as week_num
       ,count(distinct week1.member_id) as week1_member_num
       ,count(distinct week2.member_id) as week2_member_num
       ,count(distinct week3.member_id) as week3_member_num
  from (
    select  member_id 
          , order_id
      from fct_order
      where date betwenn 'week1_monday' and 'week1_sunday' 
  ) as week1
  left join (
    select  member_id 
          , order_id
      from fct_order
      where date betwenn 'week2_monday' and 'week2_sunday'
  ) as week2
  on week2.member_id = week1.member2 
left join (
    select  member_id 
          , order_id
      from fct_order
      where date betwenn 'week3_monday' and 'week3_sunday'
  ) as week3
  on week3.member_id = week1.member2   

这个方法的缺点:

  • 一次只能计算一周的留存,不能一次性计算出多周的数据
  • 跟踪的周期变长后,计算效率低会很低

方法2

可以先给一个周期内的会员打标签。我们可以使用 case when 来判断没周内是否有消费记录,例如,一个会员 A 分别在 23、24 周内有消费记录,25 周没有,可以使用如下的 类似的 sql 进行打标签:

select member_id 
        max(if(date between 'week1_monday' and 'week1_sunday',1,0 )) as week1_consumption
       ,max(if(date between 'week2_monday' and 'week2_sunday',1,0 )) as week2_consumption
       ,max(if(date between 'week3_monday' and 'week3_sunday',1,0 )) as week3_consumption
  from fct_order
 where date between 'week1_monday' and 'week3_sunday'

会员 A 可以得到下面的结果:

member_id week1_consumption week2_consumption week3_consumption
A 1 1 0

把会员的标签数据放到一个临时(tmp_member_flag)表里面最后计算三周的情况:

select  week_num 
       ,count(distinct if(flag.week1_consumption=1,member_id,null)) as '第一周的会员数'
       ,sum(if(flag.week1_consumption=1,sale_amt,0)) as '第一周会员消费额'
       ,count(distinct if(flag.week1_consumption=1 and flag.week2_consumption=1 
                          ,member_id,null)) as '第二周的会员留存数'
       ,sum(if(flag.week1_consumption=1 and flag.week1_consumption=1 
                          ,sale_amt,0)) as '第二周留存会员消费额'
       ,count(distinct if(flag.week1_consumption=1 
                           and flag.week2_consumption=1
                           and flag.week3_consumption=1 
                          ,member_id,null)) as '第三周的会员留存数'
       ,sum(if(flag.week1_consumption=1 
               and flag.week2_consumption=1
               and flag.week3_consumption=1 
                          ,sale_amt,0)) as '第三周留存会员消费额'
       ,count(distinct if(flag.week1_consumption=0 
                           and flag.week2_consumption=1
                          ,member_id,null)) as '第二周的新会员'
       ,sum(if(flag.week1_consumption=0 
               and flag.week2_consumption=1
               ,sale_amt,0)) as '第二周新会员消费额'                          
       ,count(distinct if(flag.week1_consumption=0 
                           and flag.week2_consumption=1
                           and flag.week3_consumption=1
                          ,member_id,null)) as '第二周在第三周的留存数'
       ,sum(if(flag.week1_consumption=0 
               and flag.week2_consumption=1
               and flag.week3_consumption=1
               ,sale_amt,0)) as '第二周在第三周留存会员消费额'
  from fct_order as order 
 left join tmp_member_flag as flag
    on order.member_id = flag.member_id 
 where date between 'week1_monday' and 'week3_sunday'

这样可以一次计算出三周的留率

猜你喜欢

转载自blog.csdn.net/bluedraam_pp/article/details/84844243
今日推荐