SQL - 新客户保留 - 环比

SQL - New customers Retention - MoM

我正在尝试确定我们每个月获得的新客户的保留期。 已经从交易中识别出新客户逻辑,我不知道如何开始 M1 到 M10

我需要得到类似下面的内容来解释 table,在 1 月份我们获得了 2500 个客户,其中 2500 个新客户中只有 1600 个在 M1(2 月)进行了交易,其中1600只成交1200 M2(Mar)等等

同样,在2月份,我们获得了2k客户,其中只有1100个在M1(这里M1指的是3月)进行了交易,而这1100个中只有800个在M2(这里的M2指的是4月)进行了交易

M2是M1的子集,M3是M2的子集等等。

使用 SQL Server 2012,我想避免由于对我的角色和访问权限的某些限制而对数据进行预处理。 任何具有 sql 逻辑的线索都会有所帮助。

我建议如下:

  • 按客户和月份汇总。
  • 使用 window 函数获取客户出现的最早月份。
  • 使用row_number()
  • 获取没有下个月的最后一个月
  • 汇总。

在 SQL 中,这看起来像:

select year(first_yyyymm), month(first_yyyymm),
       count(*) as new_customers,
       sum(case when seqnum = 1 then 1 else 0 end) as m1,
       sum(case when seqnum = 2 then 1 else 0 end) as m2,
       sum(case when seqnum = 3 then 1 else 0 end) as m3,
       sum(case when seqnum = 4 then 1 else 0 end) as m4,
       sum(case when seqnum = 5 then 1 else 0 end) as m5,
       sum(case when seqnum = 6 then 1 else 0 end) as m6,
       sum(case when seqnum = 7 then 1 else 0 end) as m7,
       sum(case when seqnum = 8 then 1 else 0 end) as m8,
       sum(case when seqnum = 9 then 1 else 0 end) as m9,
       sum(case when seqnum = 10 then 1 else 0 end) as m10
from (select customer, eomonth(date) as yyyymm,
             min(eomonth(date)) over (partition by customer) as first_eomonth,
             row_number() over (partition by customer order by eomonth(date)) as seqnum
      from transactions t
      group by customer, eomonth(date)
     ) t
where datediff(month, first_yyyymm, yyyymm) = seqnum - 1
group by year(first_yyyymm), month(first_yyyymm)
order by min(first_yyyymm);

根据戈登的回答,我提出解决方案:http://sqlfiddle.com/#!18/f6785/3

select
  year(first_yyyymm),
  month(first_yyyymm),
  count(distinct customer_id) as new_customers,
  sum(case when seqnum = 1 then 1 else 0 end) as m1,
  sum(case when seqnum = 2 then 1 else 0 end) as m2,
  sum(case when seqnum = 3 then 1 else 0 end) as m3,
  sum(case when seqnum = 4 then 1 else 0 end) as m4,
  sum(case when seqnum = 5 then 1 else 0 end) as m5,
  sum(case when seqnum = 6 then 1 else 0 end) as m6,
  sum(case when seqnum = 7 then 1 else 0 end) as m7,
  sum(case when seqnum = 8 then 1 else 0 end) as m8,
  sum(case when seqnum = 9 then 1 else 0 end) as m9,
  sum(case when seqnum = 10 then 1 else 0 end) as m10
from
  (
    select
      customer_id,
      first_yyyymm, yyyymm,
      datediff(month, first_yyyymm, yyyymm) as seqnum
    from
      (
        select
          customer_id,
          eomonth(created_at) as yyyymm,
          min(eomonth(created_at))
            over (partition by customer_id) as first_yyyymm
        from transactions t
        group by customer_id, eomonth(created_at)
      ) t
  ) t
group by year(first_yyyymm), month(first_yyyymm)
order by month(first_yyyymm);

对于数据:

结果应为:

编辑

这是另一个解决方案,只计算每个月有交易的客户。

http://sqlfiddle.com/#!18/ad3803/2