You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于起止日期统计月度活跃客户数的技术咨询

计算月度活跃客户数的实现方法

现有客户数据表:

CustomerStart DateEnd Date
12020-012020-04
22020-012020-03
32020-02

规则:无End Date的客户视为持续活跃,需计算每个月份的活跃客户数量,期望输出如示例所示。

SQL 实现方案

核心逻辑是先生成目标统计月份序列,再关联客户表判断每个客户是否在对应月份处于活跃状态。

1. 生成固定月份序列(以MySQL为例)

如果统计范围固定(比如2020-01至2020-06),直接构造月份列表:

WITH months AS (
    SELECT '2020-01' AS month UNION ALL
    SELECT '2020-02' UNION ALL
    SELECT '2020-03' UNION ALL
    SELECT '2020-04' UNION ALL
    SELECT '2020-05' UNION ALL
    SELECT '2020-06'
)

若需动态生成(从最早开始日期到当前月份),用递归CTE:

WITH RECURSIVE months AS (
    SELECT MIN(STR_TO_DATE(start_date, '%Y-%m')) AS month_date
    FROM customers
    UNION ALL
    SELECT DATE_ADD(month_date, INTERVAL 1 MONTH)
    FROM months
    WHERE month_date <= CURDATE() -- 可替换为指定结束日期
)
SELECT DATE_FORMAT(month_date, '%Y-%m') AS month FROM months;

2. 关联客户表计算活跃数

将月份序列与客户表关联,判断客户活跃区间是否覆盖当前月份:

WITH months AS (
    SELECT '2020-01' AS month UNION ALL
    SELECT '2020-02' UNION ALL
    SELECT '2020-03' UNION ALL
    SELECT '2020-04' UNION ALL
    SELECT '2020-05' UNION ALL
    SELECT '2020-06'
)
SELECT
    m.month,
    COUNT(DISTINCT c.customer) AS active_customers,
    GROUP_CONCAT(DISTINCT c.customer ORDER BY c.customer SEPARATOR '+') AS customer_list
FROM months m
LEFT JOIN customers c
ON STR_TO_DATE(m.month, '%Y-%m') >= STR_TO_DATE(c.start_date, '%Y-%m')
AND (c.end_date IS NULL OR STR_TO_DATE(m.month, '%Y-%m') <= STR_TO_DATE(c.end_date, '%Y-%m'))
GROUP BY m.month
ORDER BY m.month;

该查询会直接输出每个月份的活跃客户数及对应客户列表,与示例格式匹配。

Python Pandas 实现方案

通过生成月度时间序列,逐个判断客户活跃区间是否覆盖目标月份,最终统计结果。

1. 准备数据与格式转换

import pandas as pd

# 构造客户数据集
data = {
    'Customer': [1, 2, 3],
    'Start Date': ['2020-01', '2020-01', '2020-02'],
    'End Date': ['2020-04', '2020-03', None]
}
df = pd.DataFrame(data)

# 转换为日期格式,无结束日期的设为指定统计截止月份(如2020-06)
df['Start Date'] = pd.to_datetime(df['Start Date'], format='%Y-%m')
df['End Date'] = pd.to_datetime(df['End Date'], format='%Y-%m').fillna(pd.to_datetime('2020-06'))

2. 生成月度序列并统计活跃数

# 生成目标统计月份列表
start_month = df['Start Date'].min().floor('D')
end_month = pd.to_datetime('2020-06')
months = pd.date_range(start=start_month, end=end_month, freq='MS').strftime('%Y-%m')

# 遍历每个月份统计活跃客户
result = []
for month in months:
    month_dt = pd.to_datetime(month)
    # 筛选当前月份活跃的客户
    active_customers = df[(df['Start Date'] <= month_dt) & (df['End Date'] >= month_dt)]
    # 整理结果格式
    result.append({
        '月份': month,
        '活跃客户数': len(active_customers),
        '客户列表': '+'.join(map(str, active_customers['Customer'].tolist()))
    })

# 打印或输出结果
for item in result:
    print(f"{item['月份']}:活跃客户数={item['活跃客户数']}(客户{item['客户列表']})")

运行后会直接输出与示例完全一致的结果文本。

内容的提问来源于stack exchange,提问作者Praveen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 03:20:17