使用 SQL 进行 RFM 客户细分分析

在数据分析领域,了解客户是推动增长的关键。客户细分最有效且经过时间检验的方法之一是 RFM 分析。但你不需要昂贵的 CRM 软件来实现它------你可以使用标准 SQL 在数据库中构建强大的 RFM 模型。

在本指南中,我们将详细介绍如何计算 Recency(最近性)、Frequency(频率)和 Monetary(金额)评分,并将客户群体细分为可操作的群组,如"Champions"(冠军客户)、"At Risk"(流失风险客户)和"New Customers"(新客户)。

RFM 细分概览,显示 Champions、At Risk 等客户群体

什么是 RFM 分析?

RFM 代表描述客户行为的三个关键指标:

  1. Recency ® - 最近性:客户最近一次购买是什么时候?
  2. Frequency (F) - 频率:客户购买的频率如何?
  3. Monetary (M) - 金额:客户花费了多少钱?

通过在这三个维度上对客户进行评分(通常从 1 到 5),你可以将他们分组到不同的细分中。例如,在所有三个类别中得分都很高的客户是"Champion"(冠军客户),而 Monetary 价值高但 Recency 低的客户可能"At Risk"(有流失风险)。

RFM 分析的价值

精准营销:根据客户细分制定针对性的营销策略,提高转化率和 ROI。

客户保留:识别流失风险客户,及时采取挽留措施。

资源优化:将营销预算和资源集中在最有价值的客户群体上。

个性化体验:为不同细分的客户提供定制化的产品推荐和服务。

步骤 1:准备数据

要执行 RFM 分析,你通常需要一个交易表。假设我们有一个 orders_rfm_demo 表,包含 customer_idorder_datetotal_amount 字段。

第一步是将这些数据聚合到客户级别。我们需要:

  • 最后订单日期MAX(order_date)
  • 订单数量COUNT(order_id)
  • 总消费SUM(total_amount)

示例数据(orders_rfm_demo 表)

order_id customer_id order_date total_amount
1001 C001 2023-12-15 150.00
1002 C001 2023-11-20 200.00
1003 C002 2023-12-28 80.00
1004 C003 2023-10-05 500.00
1005 C003 2023-11-10 300.00

聚合查询

sql 复制代码
SELECT
    customer_id,
    MAX(order_date) as last_order_date,
    COUNT(order_id) as frequency,
    SUM(total_amount) as monetary
FROM orders_rfm_demo
GROUP BY customer_id;

聚合结果示例

customer_id last_order_date frequency monetary
C001 2023-12-15 2 350.00
C002 2023-12-28 1 80.00
C003 2023-11-10 2 800.00

步骤 2:计算 RFM 值

现在,让我们将这些原始数字转换为"R"、"F"和"M"值。

对于 Recency ,我们需要自最后一次购买以来的天数。我们将 last_order_date 与参考日期(通常是"今天"或分析日期)进行比较。

计算 Recency 的查询

sql 复制代码
SELECT
    customer_id,
    julianday('2024-01-01') - julianday(MAX(order_date)) as recency_days,
    COUNT(order_id) as frequency,
    SUM(total_amount) as monetary
FROM orders_rfm_demo
GROUP BY customer_id;

注意 :在大多数 SQL 方言(如 PostgreSQL)中,你可能使用 CURRENT_DATE - MAX(order_date),但这里我们使用固定日期以确保可重现性。

计算结果示例

customer_id recency_days frequency monetary
C001 17 2 350.00
C002 4 1 80.00
C003 52 2 800.00

不同数据库的日期计算

PostgreSQL

sql 复制代码
CURRENT_DATE - MAX(order_date) as recency_days

MySQL

sql 复制代码
DATEDIFF(CURRENT_DATE, MAX(order_date)) as recency_days

SQL Server

sql 复制代码
DATEDIFF(day, MAX(order_date), GETDATE()) as recency_days

SQLite

sql 复制代码
julianday('2024-01-01') - julianday(MAX(order_date)) as recency_days

步骤 3:使用 NTILE 确定 RFM 评分

这是魔法发生的地方。我们不能只看原始金额,因为不同企业的消费范围差异很大。相反,我们使用以下逻辑对客户进行相对排名:"前 20% 得 5 分,后 20% 得 1 分"。

SQL 窗口函数 NTILE(5) 非常适合这个任务。

评分逻辑

  • Recency 评分 :天数越少越好(5 分),天数越多越差(1 分)。NTILE 将 1 分配给最低值。所以对于 Recency(低值好),低 recency_days 会得到 NTILE 1。我们想要相反的结果。我们可以对 NTILE 函数使用 recency_days DESC 排序,这样最大的天数(最差)得到 1,最小的(最好)得到 5。
  • Frequency 评分 :越高越好。按 frequency ASC 排序。
  • Monetary 评分 :越高越好。按 monetary ASC 排序。

完整的 RFM 评分查询

sql 复制代码
WITH base_metrics AS (
  SELECT 
    customer_id,
    -- 计算距离最后订单的天数(假设分析日期为 2024-01-01)
    CAST(julianday('2024-01-01') - julianday(MAX(order_date)) AS INTEGER) as recency_days,
    COUNT(order_id) as frequency,
    SUM(total_amount) as monetary
  FROM orders_rfm_demo
  GROUP BY customer_id
),
scored_data AS (
  SELECT 
    customer_id,
    recency_days,
    frequency,
    monetary,
    -- 较低的 recency_days 更好,所以我们按 DESC 排序以获得最佳的 5 分
    NTILE(5) OVER (ORDER BY recency_days DESC) as r_score,
    NTILE(5) OVER (ORDER BY frequency ASC) as f_score,
    NTILE(5) OVER (ORDER BY monetary ASC) as m_score
  FROM base_metrics
)
SELECT 
  customer_id,
  recency_days,
  frequency,
  monetary,
  r_score,
  f_score,
  m_score
FROM scored_data
ORDER BY r_score DESC, f_score DESC, m_score DESC;

评分结果示例

customer_id recency_days frequency monetary r_score f_score m_score
C002 4 1 80.00 5 1 1
C001 17 2 350.00 4 3 3
C003 52 2 800.00 2 3 5

NTILE 函数详解

NTILE(n) 将结果集分为 n 个大致相等的组,并为每行分配一个组号(1 到 n)。

工作原理

  • 如果有 100 个客户,NTILE(5) 将它们分为 5 组,每组 20 个客户
  • 第 1 组得 1 分,第 2 组得 2 分,依此类推
  • 排序顺序决定了哪些客户进入哪个组

为什么 Recency 使用 DESC 排序

  • NTILE 默认将 1 分配给最低值
  • 对于 Recency,低天数(最近购买)应该得高分
  • 使用 DESC 排序后,最大天数(最久未购买)得 1 分,最小天数(最近购买)得 5 分

步骤 4:创建可读的客户细分

拥有像"555"或"121"这样的评分对机器有用,但人类更喜欢标签。我们可以使用 CASE 语句将这些评分转换为命名的细分。

常见的细分定义

  • Champions(冠军客户):R=4-5, F=4-5, M=4-5
  • Loyal Customers(忠诚客户):F=3-5, R=3-5(无论 M 如何)
  • Potential Loyalists(潜在忠诚客户):最近的客户,频率中等
  • New Customers(新客户):R=4-5, F=1
  • At Risk(流失风险客户):R≤2, F≥3(即将流失)
  • Standard(标准客户):其他

添加客户细分的完整查询

sql 复制代码
WITH base_metrics AS (
  SELECT 
    customer_id,
    CAST(julianday('2024-01-01') - julianday(MAX(order_date)) AS INTEGER) as recency_days,
    COUNT(order_id) as frequency,
    SUM(total_amount) as monetary
  FROM orders_rfm_demo
  GROUP BY customer_id
),
scored_data AS (
  SELECT 
    customer_id,
    recency_days,
    frequency,
    monetary,
    NTILE(5) OVER (ORDER BY recency_days DESC) as r_score,
    NTILE(5) OVER (ORDER BY frequency ASC) as f_score,
    NTILE(5) OVER (ORDER BY monetary ASC) as m_score
  FROM base_metrics
)
SELECT 
  customer_id,
  recency_days,
  frequency,
  monetary,
  r_score,
  f_score,
  m_score,
  CASE
    WHEN r_score >= 4 AND f_score >= 4 AND m_score >= 4 THEN 'Champions'
    WHEN r_score >= 3 AND f_score >= 3 THEN 'Loyal Customers'
    WHEN r_score >= 4 AND f_score = 1 THEN 'New Customers'
    WHEN r_score <= 2 AND f_score >= 3 THEN 'At Risk'
    ELSE 'Standard'
  END as customer_segment
FROM scored_data
ORDER BY r_score DESC, f_score DESC, m_score DESC;

最终结果示例

customer_id recency_days frequency monetary r_score f_score m_score customer_segment
C002 4 1 80.00 5 1 1 New Customers
C001 17 2 350.00 4 3 3 Loyal Customers
C003 52 2 800.00 2 3 5 At Risk

客户细分详解

Champions(冠军客户)

  • 特征:最近购买、频繁购买、高消费
  • 营销策略:VIP 待遇、独家优惠、新品首发、推荐计划
  • 目标:保持忠诚度,鼓励口碑传播

Loyal Customers(忠诚客户)

  • 特征:定期购买、中高消费
  • 营销策略:会员奖励、生日优惠、忠诚度积分
  • 目标:提升到 Champions 级别

Potential Loyalists(潜在忠诚客户)

  • 特征:最近购买、中等频率
  • 营销策略:个性化推荐、会员计划邀请
  • 目标:增加购买频率

New Customers(新客户)

  • 特征:最近首次购买
  • 营销策略:欢迎邮件、新手指南、首单优惠
  • 目标:促进第二次购买

At Risk(流失风险客户)

  • 特征:曾经频繁购买,但最近未购买
  • 营销策略:挽回优惠、问卷调查、个性化沟通
  • 目标:重新激活

Hibernating(休眠客户)

  • 特征:很久未购买
  • 营销策略:重新激活活动、特别折扣
  • 目标:唤醒兴趣

Lost(流失客户)

  • 特征:很久未购买且消费低
  • 营销策略:最后一次挽回尝试或放弃
  • 目标:决定是否值得投入资源

SQL 中 RFM 的最佳实践

1. 过滤异常值

在计算之前排除退货(负值)或测试交易。

sql 复制代码
WHERE total_amount > 0 
  AND customer_id NOT LIKE 'TEST%'

2. 时间范围很重要

RFM 通常在滑动窗口(例如,过去 12 个月)上计算。较旧的数据可能会扭曲 Recency。

sql 复制代码
WHERE order_date >= DATE_SUB(CURRENT_DATE, INTERVAL 12 MONTH)

3. 分箱分布

NTILE 强制等大小的组。如果你的数据倾斜(例如,90% 的客户只购买过一次),NTILE 可能会任意分割它们。在这种情况下,使用自定义 CASE 范围进行评分(例如,"Frequency 1 = 1 分","Freq 2-5 = 3 分")可能比严格的百分位数更准确。

sql 复制代码
CASE 
  WHEN frequency = 1 THEN 1
  WHEN frequency BETWEEN 2 AND 5 THEN 3
  WHEN frequency > 5 THEN 5
END as f_score

4. 定期更新

RFM 分析应该定期更新(每周或每月),以反映最新的客户行为。

5. 结合其他指标

RFM 可以与其他指标结合使用,如客户生命周期价值(CLV)、客户获取成本(CAC)等。

实际应用场景

1. 电商平台

根据 RFM 细分发送个性化邮件营销活动,提高转化率。

2. 订阅服务

识别流失风险客户,提前采取挽留措施,降低流失率。

3. 零售业

优化库存管理,为不同细分的客户准备合适的产品。

4. 金融服务

识别高价值客户,提供专属理财服务和产品。

5. 会员制企业

设计分层会员计划,根据 RFM 评分提供差异化权益。

性能优化

1. 创建索引

为常用的查询列创建索引:

sql 复制代码
CREATE INDEX idx_customer_order ON orders_rfm_demo(customer_id, order_date);

2. 物化视图

对于大数据集,考虑使用物化视图:

sql 复制代码
CREATE MATERIALIZED VIEW rfm_scores AS
SELECT ...

3. 分区表

对于非常大的交易表,考虑按日期分区:

sql 复制代码
CREATE TABLE orders_rfm_demo (
  ...
) PARTITION BY RANGE (order_date);

结论

RFM 分析是数据科学中的低垂果实,可以立即提供价值。通过直接在 SQL 中实现它,你可以创建动态仪表板报告,随着新订单的到来自动更新。无需导出 CSV 或运行 Python 脚本------你的数据库可以处理繁重的工作!

关键要点

  • RFM 分析基于三个维度:Recency、Frequency、Monetary
  • 使用 NTILE(5) 将客户分为 5 个等级
  • 根据 RFM 评分组合定义客户细分
  • 为不同细分制定针对性的营销策略
  • 定期更新分析以反映最新的客户行为

掌握 SQL 中的 RFM 分析,你将能够更好地理解客户,优化营销策略,提高客户保留率和收入。


相关文章推荐


本文转载自 www.hisqlboy.com

原文标题:Customer Segmentation with RFM Analysis in SQL

原文链接:https://www.hisqlboy.com/blog/customer-segmentation-rfm-analysis-sql

原作者:SQL Boy Team

转载日期:2026-02-11

著作权归原作者所有。本文仅用于学习交流,非商业用途。

相关推荐
老纪的技术唠嗑局3 小时前
超级干货分享:中小企业使用 OceanBase 实践经验汇总
数据库
CLOUD ACE3 小时前
谷歌云代理|零售商Target 如何利用 Spanner Graph 提升零售发现体验并将数据库维护成本降低 50%
数据库·零售
MuMuMu12233 小时前
工业园区 VOCs 绿岛集中治理:越华环保集团项目技术方案与工程实践
大数据·运维
品牌测评4 小时前
大模型推理算力平台推荐分享|六家平台计费与架构拆解
大数据·人工智能·架构
LedgerNinja4 小时前
WEEX 真实情况如何?交易平台如何判断是否可靠
大数据·人工智能·区块链
微三云 - 廖会灵 (私域系统开发)4 小时前
智慧社区运营破局:“消费返物业费” 模式的数字化架构与落地实践
大数据·架构
少晓年4 小时前
从 MySQL 迁移到人大金仓 KingbaseES:完整指南与实践
数据库·mysql
SelectDB4 小时前
Apache Doris AI RAG 实战:从基础 RAG 到知识图谱增强的技术能力与选型
数据库
SelectDB5 小时前
电商企业 PostgreSQL 迁移 Apache Doris:80TB 分析数据统一平台技术能力与实践
数据库
SelectDB5 小时前
阶跃星辰 Agent 可观测:Apache Doris / SelectDB 的技术能力与实践
数据库