Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 4

#RFM Analysis

WITH
customer_data AS(
SELECT
`Customer_ID`,
`Customer_Name`,
CAST(MAX(Order_Date) AS DATETIME) AS last_transaction_date,
ROUND(SUM(Sales), 2) AS monetary,
COUNT(DISTINCT Order_ID) AS frequency
FROM
`customeranalytics-382708.customer_analyticsDS.customer_data `
GROUP BY
`Customer_ID`,
`Customer_Name` ),
customer_quantiles AS (
SELECT
`Customer_ID`,
`Customer_Name`,
monetary,
frequency,
DATETIME_DIFF(CAST('2019-01-31' AS DATETIME), last_transaction_date, DAY) AS recency,
NTILE(5) OVER (ORDER BY monetary DESC) AS monetary_quantile,
NTILE(5) OVER (ORDER BY frequency DESC) AS frequency_quantile
FROM
customer_data ),
customer_score AS (
SELECT
`Customer_ID`,
`Customer_Name`,
monetary,
frequency,
recency,
monetary_quantile,
frequency_quantile,
NTILE(5) OVER (ORDER BY recency ASC) AS recency_quantile,
6 - monetary_quantile AS m_score,
6 - frequency_quantile AS f_score
FROM
customer_quantiles ),
rfm_score AS (
SELECT
*,
6 - recency_quantile AS r_score
FROM
customer_score ),
rfm_scores AS (
SELECT
`Customer_ID`,
`Customer_Name`,
monetary,
frequency,
recency,
m_score,
f_score,
r_score,
CONCAT ( r_score, f_score, m_score) AS rfm_Score
FROM
rfm_score ),
rfm_segments AS (
SELECT
`Customer_ID`,
`Customer_Name`,
rfm_Score,
CASE
WHEN rfm_Score IN ('555', '554', '544', '545', '454', '455', '445') THEN 'Champion'
WHEN rfm_Score IN ('543',
'444',
'435',
'355',
'354',
'345',
'344',
'335') THEN 'Loyal'
WHEN rfm_Score IN ('553', '551', '552', '541', '542', '533', '532', '531', '452', '451', '442', '441', '431', '453', '433', '432', '423', '3
53', '352', '351', '342', '341', '333', '323') THEN 'Potential Loyalist'
WHEN rfm_Score IN ('512',
'511',
'422',
'421',
'412',
'411',
'311') THEN 'Recent'
WHEN rfm_Score IN ('535', '534', '443', '434', '343', '334', '325', '324') THEN 'Needs Attention'
WHEN rfm_Score IN ('331',
'321',
'312',
'221',
'213') THEN 'About to Sleep'
WHEN rfm_Score IN ('255', '254', '245', '244', '253', '252', '243', '242', '235', '234', '225', '224', '153', '152', '145', '143', '142', '1
35', '134', '133', '125', '124') THEN 'At Risk'
WHEN rfm_Score IN ('155',
'154',
'144',
'214',
'215',
'115',
'114',
'113') THEN 'Cant Lose'
WHEN rfm_Score IN ('332', '322', '231', '241', '251', '233', '232', '223', '222', '132', '123', '122', '212', '211') THEN 'Hibernating
'
ELSE
'Lost'
END
AS rfm_segment
FROM
rfm_scores )
SELECT
`Customer_ID`,
`Customer_Name`,
rfm_Score,
RFM_segment
FROM
rfm_segments;

#Median_Days_between_orders
WITH
median_days_bw_orders AS(
SELECT
`Customer_ID`,
`Customer_Name`,
`Order_ID`,
Order_Date,
LAG(Order_Date) OVER (PARTITION BY `Customer_ID`, `Customer_Name` ORDER BY Order_Date) AS previous_order
_dates
FROM
`customeranalytics-382708.customer_analyticsDS.customer_data `
GROUP BY
`Customer_ID`,
`Customer_Name`,
`Order_ID`,
Order_Date ),
visit_diffs AS (
SELECT
*,
DATE_DIFF(Order_Date, previous_order_dates, DAY) AS visit_diff
FROM
median_days_bw_orders
WHERE
previous_order_dates IS NOT NULL )
SELECT
`Customer_ID`,
`Customer_Name`,
APPROX_QUANTILES(visit_diff, 2)[
OFFSET
(1)] AS median_days_bw_orders
FROM
visit_diffs
GROUP BY
`Customer_ID`,
`Customer_Name`;

#Category_Purchased BY customer
WITH
category_customer AS(
SELECT
`Customer_ID`,
`Customer_Name`,
COUNT(DISTINCT Product_ID) AS n_Items_purchased,
Category
FROM
`customeranalytics-382708.customer_analyticsDS.customer_data `
GROUP BY
`Customer_ID`,
`Customer_Name`,
Category )
SELECT
*,
MAX(n_Items_purchased) OVER (PARTITION BY `Customer_ID`) AS most_items_purchased
FROM
category_customer;

#Other Customer detail


WITH
customer_detail AS(
SELECT
`Customer_ID`,
`Customer_Name`,
CAST(MIN(Order_Date) AS DATETIME) AS first_transaction_date,
CAST(MAX(Order_Date) AS DATETIME) AS last_transaction_date,
ROUND(SUM(Sales), 2) AS total_spent,
ROUND(SUM(Sales)/COUNT(DISTINCT Order_ID),2) AS customer_order_value
FROM
`customeranalytics-382708.customer_analyticsDS.customer_data `
GROUP BY
`Customer_ID`,
`Customer_Name` )
SELECT
*
FROM
customer_detail;

You might also like