SQL

Full RFM scoring: recency, frequency, monetary in quintiles

A two-CTE pipeline: aggregate the three RFM axes per customer, score them in quintiles with NTILE, then produce readable segmentation (Champion, VIP to win back, Lost) ready for the CRM.

Prerequisites

PostgreSQL, MySQL 8+, SQL Server (NTILE)

SQL
WITH base AS (
    SELECT customer_id,
           CURRENT_DATE - MAX(order_date) AS recence_j,
           COUNT(*)    AS frequence,
           SUM(amount) AS montant
    FROM orders
    WHERE order_date >= CURRENT_DATE - INTERVAL '24 months'
    GROUP BY customer_id
),
scores AS (
    SELECT *,
        6 - NTILE(5) OVER (ORDER BY recence_j) AS score_r,
        NTILE(5) OVER (ORDER BY frequence)     AS score_f,
        NTILE(5) OVER (ORDER BY montant)       AS score_m
    FROM base
)
SELECT customer_id, recence_j, frequence, montant,
       score_r || score_f || score_m AS rfm,
       CASE
           WHEN score_r >= 4 AND score_f >= 4 AND score_m >= 4 THEN 'Champion'
           WHEN score_r <= 2 AND score_m >= 4 THEN 'VIP à réactiver'
           WHEN score_r <= 2 AND score_f <= 2 THEN 'Perdu'
           ELSE 'Standard'
       END AS segment
FROM scores
ORDER BY montant DESC
LIMIT 6;

Result

 customer_id | recence_j | frequence | montant  | rfm |     segment
-------------+-----------+-----------+----------+-----+-----------------
        4021 |         6 |        38 | 18420.50 | 555 | Champion
        4187 |       148 |        24 | 12305.00 | 245 | VIP à réactiver
        4302 |        12 |        19 |  6840.75 | 544 | Champion
        4099 |        67 |        11 |  4210.00 | 334 | Standard
        4233 |       291 |         3 |  1980.25 | 113 | Perdu
        4150 |        38 |         7 |   820.00 | 421 | Standard
(6 rows)
SQLRFMSegmentationMarketingMulti-CTE

Related snippets

Back to the Data Lab