【问题标题】:Calculate number of active customers each month for last 12 months计算过去 12 个月每月的活跃客户数量
【发布时间】:2020-09-13 05:40:59
【问题描述】:

我有一个包含客户 ID、注册日期和取消日期的数据集。我想创建一个表格,显示过去 12 个月中每个月 1 日的活跃客户。

我曾尝试使用this Stack Overflow 问题,但无法解决。

如果表格有一个“月”列和一个活跃客户数量列,那就太好了。

欢迎任何帮助。

【问题讨论】:

  • 请用您正在运行的数据库标记您的问题:mysql、oracle、sql-server...?答案可能是特定于数据库的。
  • 是样本表数据还是预期结果?无论如何,我们都想要 - 作为格式化文本,而不是图像。
  • 怎么会有在注册前取消的客户?
  • 我会说在填充样本数据时疏忽了。

标签: sql


【解决方案1】:

Edit* - 使用 Sql Server 的工作示例

  1. 理想情况下,您需要在数据库中有一个日期/日历表,其中包含所有可能的日期(使用此Get all dates between two dates in SQL Server )
  2. 然后加入它以查找客户注册日期和取消日期之间的所有可能日期/月份(某些条件取决于您是否将客户视为在该月的第一天取消或在一个月内处于活跃状态的客户)如果客户在该月晚或月中注册,则被视为在该月活跃)
  3. NULL 表示客户还没有取消日期,这意味着他非常活跃。

    WITH cust (customerid,signupdate,canceldate) 
    AS 
    (SELECT 1, '2019-02-10' , '2020-03-05' UNION
     SELECT 2, '2018-12-01' , '2019-12-29' UNION
     SELECT 3, '2014-04-15' , '2019-09-15' UNION
     SELECT 4, '2019-02-10' , '2020-01-04' UNION
     SELECT 5, '2020-02-10' ,  NULL        UNION
     SELECT 6, '2019-07-10' , '2018-01-01' UNION
     SELECT 7, '2019-09-10' , '2020-05-01' UNION
     SELECT 8, '2019-02-06' ,  NULL        UNION
     SELECT 9, '2018-02-10' , '2020-07-29' UNION
     SELECT 10, '2020-02-10' , '2020-04-01' 
    )
    
    Select CONVERT(CHAR(6),cal.record_date,112) as yyyymm , 
           COUNT(DISTINCT c.customerid) as Active_Custs
    FROM tbl_Calendar cal
    JOIN CUST c ON CONVERT(CHAR(6),cal.record_date,112) BETWEEN CONVERT(VARCHAR(6),cast(c.signupdate as date),112) and CONVERT(CHAR(6),ISNULL(cast(c.canceldate as date),getdate()),112) 
    GROUP BY CONVERT(CHAR(6),cal.record_date,112)
    ORDER BY 1
    
    yyyymm  Active_Custs
    202007  1
    202006  1
    202005  4
    202004  5
    202003  6
    202002  6
    202001  5
    

【讨论】:

  • 很高兴它对您有所帮助。请考虑投票赞成答案以及它在 SO 中的重要性。
【解决方案2】:

如果您使用的是 Postgres,则可以使用如下内容:

select to_char(g.dt::date, 'yyyy-mm'),
       count(c.customer_id) as active_customers
from generate_series(date_trunc('month', current_date) - interval '11 month', date_trunc('month', current_date), interval '1 month') as g(dt)
  left join customer c on daterange(c.signup_date, cancel_date) @> g.dt::date
group by to_char(g.dt::date, 'yyyy-mm')
order by 1

这假设您的示例数据中的 customer_id = 6 是一个错误,因为它的 signup_date 位于 取消日期之后。

Online example

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-29
    • 2010-10-11
    • 2013-09-16
    • 1970-01-01
    • 2012-08-21
    • 2012-03-23
    相关资源
    最近更新 更多