-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy path07 Customer segmentation.sql
More file actions
73 lines (70 loc) · 2.97 KB
/
Copy path07 Customer segmentation.sql
File metadata and controls
73 lines (70 loc) · 2.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
-- CUSTOMER SEGMENTATION
-- rfm_buckets
-- 1. Calculate RFM scores
WITH RecencyScore AS (
SELECT customer_unique_id,
MAX(order_purchase_timestamp) AS last_purchase,
NTILE(5) OVER (ORDER BY MAX(order_purchase_timestamp) DESC) AS recency
FROM orders
JOIN customers USING (customer_id)
WHERE order_status = 'delivered'
GROUP BY customer_unique_id
),
FrequencyScore AS (
SELECT customer_unique_id,
COUNT(order_id) AS total_orders,
NTILE(5) OVER (ORDER BY COUNT(order_id) DESC) AS frequency
FROM orders
JOIN customers USING (customer_id)
WHERE order_status = 'delivered'
GROUP BY customer_unique_id
),
MonetaryScore AS (
SELECT customer_unique_id,
SUM(price) AS total_spent,
NTILE(5) OVER (ORDER BY SUM(price) DESC) AS monetary
FROM orders
JOIN order_items USING (order_id)
JOIN customers USING (customer_id)
WHERE order_status = 'delivered'
GROUP BY customer_unique_id
),
-- 2. Assign each customer to a group
RFM AS (
SELECT last_purchase, total_orders, total_spent,
CASE
WHEN recency = 1 AND frequency + monetary IN (1, 2, 3, 4) THEN "Champions"
WHEN recency IN (4, 5) AND frequency + monetary IN (1, 2) THEN "Can't Lose Them"
WHEN recency IN (4, 5) AND frequency + monetary IN (3, 4, 5, 6) THEN "Hibernating"
WHEN recency IN (4, 5) AND frequency + monetary IN (7, 8, 9, 10) THEN "Lost"
WHEN recency IN (2, 3) AND frequency + monetary IN (1, 2, 3, 4) THEN "Loyal Customers"
WHEN recency = 3 AND frequency + monetary IN (5, 6) THEN "Needs Attention"
WHEN recency = 1 AND frequency + monetary IN (7, 8) THEN "Recent Users"
WHEN recency = 1 AND frequency + monetary IN (5, 6) OR
recency = 2 AND frequency + monetary IN (5, 6, 7, 8) THEN "Potentital Loyalists"
WHEN recency = 1 AND frequency + monetary IN (9, 10) THEN "Price Sensitive"
WHEN recency = 2 AND frequency + monetary IN (9, 10) THEN "Promising"
WHEN recency = 3 AND frequency + monetary IN (7, 8, 9, 10) THEN "About to Sleep"
END AS RFM_Bucket
FROM RecencyScore
JOIN FrequencyScore USING (customer_unique_id)
JOIN MonetaryScore USING (customer_unique_id)
)
-- 3. Calculate group statistics for plotting
SELECT RFM_Bucket,
AVG(JULIANDAY('now') - JULIANDAY(last_purchase)) AS avg_days_since_purchase,
AVG(total_spent / total_orders) AS avg_sales_per_customer,
COUNT(*) AS customer_count
FROM RFM
GROUP BY RFM_Bucket;
-- repeat_customer_proportion
WITH CustomerOrders AS (
SELECT COUNT(orders.order_id) AS order_count
FROM orders JOIN customers USING (customer_id)
GROUP BY customers.customer_unique_id
)
SELECT
CASE WHEN order_count > 1 THEN 'repeat' ELSE 'one-time' END AS order_type,
ROUND(100.0 * COUNT(*) / (SELECT COUNT(*) FROM CustomerOrders), 1) AS proportion
FROM CustomerOrders
GROUP BY order_type;