【问题标题】:SQLite: generating customer counts for a date range (months) using a normalized tableSQLite:使用规范化表生成日期范围(月)的客户计数
【发布时间】:2020-05-27 09:42:02
【问题描述】:

我在 SQLite 中有一个销售漏斗数据集,每一行代表通过漏斗的移动。由于潜在客户可以通过多种方式通过漏斗(甚至可能倒退),因此我不打算扁平化/非规范化表格。我如何计算“到今天为止每月的客户数量”?

customer | opp_value | status_old   | status_new | current_status | status_change_date | current_lead_status | lead_created_date
cust_8   | 22        | confirmed    | paying     | paying         | 2020-01-01         | Customer            | 2020-01-01
cust_9   | 23        | confirmed    | paying     | churned        | 2020-01-03         | Customer            | 2020-01-02
cust_9   | 23        | paying       | churned    | churned        | 2020-03-24         | Customer            | 2020-02-25
cust_13  | 30        | negotiation  | lost       | paying         | 2020-04-03         | Lost                | 2020-03-20
cust_14  | 45        | qualified    | confirmed  | paying         | 2020-03-03         | Customer            | 2020-02-28
cust_14  | 45        | confirmed    | paying     | paying         | 2020-04-03         | Customer            | 2020-02-28
...      | ...       | ...          | ...        | ...            | ...                | ...                 | ...

我们假设我们使用月末来定义客户是否仍在我们身边。

结果,加上上面的数据应该是:

month    | customers
Jan-2020 | 2          (cust_8, cust_9)
Feb-2020 | 1          (cust_8, cust_9) 
Mar-2020 | 1          (cust_8) # cust_9 churned
Apr-2020 | 2          (cust_8, cust_14)
May-2020 | 2          (cust_8, cust_14)

我真正想了解的部分是如何创建month 列,因为我不能依赖status_change_date 的日期,因为可能缺少记录。是否必须手动生成该列?我知道我可以使用手动生成日期:

WITH RECURSIVE cnt (
   x
) AS (
  SELECT 0
    UNION ALL
  SELECT x + 1
  FROM cnt
  LIMIT (
    SELECT
      ROUND(((julianday ('2020-05-01') - julianday ('2020-01-01')) / 30) + 1))
)

SELECT
  date(julianday ('2020-01-01'), '+' || x || ' month') AS month
FROM cnt

但想知道是否有更好的方法?创建快照表并为每个日期生成每个客户的当前状态可能更容易吗?

【问题讨论】:

  • 是的,您可以创建一个包含日期的正式表格。您需要这方面的帮助,还是需要帮助来生成上面显示的结果?
  • 可能两者兼有,但目前大多停留在日期部分。

标签: sql sqlite


【解决方案1】:

如果您有日期,则可以使用蛮力方法。这将确定每个客户在每个日期的最新状态:

select d.date,
       sum(as_of_status = 'paying')
from (select distinct d.date, t.customer,
             first_value(status_new) over (partition by d.date, t.customer order by t. status_change_date desc) as as_of_status
      from dates d join
           t
           on t.status_change_date <= d.date
     ) dc
group by d.date
order by d.date;

【讨论】:

    猜你喜欢
    • 2013-07-07
    • 2010-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-10
    相关资源
    最近更新 更多