You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何用SQL计算用户平均购买频率?求算法思路与实现代码

计算用户平均购买频率的思路与SQL实现

我完全理解你的需求——你要的不是简单的「总购买量/总用户数」,而是每个用户在指定时间段内的购买频率的平均值,比如得到“用户每月平均购买2次”这类直观结果。这个需求很贴合实际业务分析,我来一步步拆解思路并给出可落地的SQL代码。

核心算法思路

要得到你想要的结果,我们需要分三步推进:

  1. 确定统计周期的精准时长:先把你指定的时间范围转换成统一的时长单位(比如月、天,这里以月为例匹配你说的“每月平均”),尽量避免月份天数差异带来的误差。
  2. 计算单个用户的购买频率:对每个用户,统计该时间段内的购买次数,再除以周期时长,得到这个用户的「单位时间购买次数」(比如每月买几次)。
  3. 求所有用户的频率平均值:把每个用户的频率值取平均,这里可以选择是否包含无购买记录的用户(默认建议包含,更贴合“所有用户”的统计口径)。

另外补充一种精细化思路:如果想基于购买间隔计算(比如用户每次购买的平均间隔,再取倒数得到频率),这种适合分析用户的购买规律性,但要注意仅适用于有多次购买的用户,和第一种思路的适用场景略有不同。

SQL代码实现

假设你的表结构为:

  • users表:至少包含user_id(用户唯一标识)
  • purchases表:包含user_id(关联用户)、purchase_date(购买日期)、purchase_id(购买记录唯一标识,可选)

基础版实现(贴合“每月平均购买X次”需求)

以MySQL为例,代码如下:

-- 1. 定义统计时间范围
SET @start_date = '2023-01-01';
SET @end_date = '2023-12-31';

-- 2. 计算统计周期的总月数(用平均每月天数30.4375,避免不同月份天数差异的误差)
SET @total_months = DATEDIFF(@end_date, @start_date) / 30.4375;

-- 3. 计算所有用户的平均购买频率
SELECT AVG(user_purchase_frequency) AS avg_monthly_purchase_frequency
FROM (
    -- 子查询:计算每个用户的个人购买频率
    SELECT 
        u.user_id,
        -- 购买次数除以总月数,无购买记录的用户频率为0
        COUNT(p.purchase_id) / NULLIF(@total_months, 0) AS user_purchase_frequency
    FROM users u
    LEFT JOIN purchases p 
        ON u.user_id = p.user_id
        AND p.purchase_date BETWEEN @start_date AND @end_date
    GROUP BY u.user_id
) AS user_frequencies;

代码关键说明

  • LEFT JOIN:确保所有用户都被统计到,包括在指定时间段内没有购买记录的用户(这类用户的频率为0)。如果只想统计有购买行为的用户,把LEFT JOIN改成INNER JOIN即可。
  • NULLIF(@total_months, 0):防止时间范围为0(比如开始和结束日期相同)时出现除以0的错误。
  • 天数转月数的方式:相比DATEDIFF(month, ...),用总天数除以平均每月天数(30.4375=365.25/12)能更精准计算周期时长,避免因2月、大月小月带来的统计偏差。

基于购买间隔的精细化实现(可选)

如果想通过相邻购买记录的时间间隔来计算用户的购买规律性,代码如下:

SET @start_date = '2023-01-01';
SET @end_date = '2023-12-31';

SELECT AVG(1 / avg_days_between_purchases * 30.4375) AS avg_monthly_purchase_frequency
FROM (
    -- 计算每个用户的平均购买间隔天数
    SELECT 
        user_id,
        AVG(DATEDIFF(next_purchase_date, purchase_date)) AS avg_days_between_purchases
    FROM (
        -- 为每条购买记录匹配下一次购买的日期
        SELECT 
            user_id,
            purchase_date,
            LEAD(purchase_date) OVER (PARTITION BY user_id ORDER BY purchase_date) AS next_purchase_date
        FROM purchases
        WHERE purchase_date BETWEEN @start_date AND @end_date
    ) AS purchase_with_next
    WHERE next_purchase_date IS NOT NULL -- 排除用户最后一次购买(无后续记录)
    GROUP BY user_id
) AS user_avg_intervals;

注意:这个方法仅统计有至少2次购买记录的用户,结果和基础版会有差异,适合分析活跃购买用户的行为规律。

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

火山引擎 最新活动