-
Notifications
You must be signed in to change notification settings - Fork 0
/
Customer Subscription.sql
267 lines (230 loc) · 7.03 KB
/
Customer Subscription.sql
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
USE customer_subscription;
-- Q1: What are the Seasonal Trends in subscription sign-ups over time,
-- and identify the GROWTH_RATE from one month to the next ?
-- Answer):-
-- 1- Seasonal Trends in subscription signups:
SELECT
YEAR(signup_date_time) AS SignUp_Year,
MONTHNAME(signup_date_time) AS SignUp_Month,
-- DAY(signup_date_time) As SignUp_Day,
COUNT(*) AS SignUps -- To determine how many signups per Month?
FROM
customer_product
GROUP BY
1, 2
ORDER BY
1, MIN(MONTH(signup_date_time));
-- 2- Identify the GROWTH_RATE from one month to the next:
WITH MonthlySignUps AS(
SELECT
YEAR(signup_date_time) AS SignUp_Year,
MONTHNAME(signup_date_time) AS SignUp_Month,
MONTH(signup_date_time) AS SignUp_MonthNumber,
COUNT(*) AS SignUps -- To determine how many signups per month
FROM
customer_product
GROUP BY
SignUp_Year, SignUp_Month, SignUp_MonthNumber
)
SELECT
SignUp_Year,
SignUp_Month,
SignUps,
LAG(SignUps) OVER (ORDER BY SignUp_Year, SignUp_MonthNumber) AS PreviousMonthSignUps, -- To retrieve the sign-ups from the previous month
ROUND(((SignUps - LAG(SignUps) OVER (ORDER BY SignUp_Year, SignUp_MonthNumber)) /
LAG(SignUps) OVER (ORDER BY SignUp_Year, SignUp_MonthNumber)) * 100, 2) AS GrowthRate
FROM
MonthlySignUps
ORDER BY
SignUp_Year, SignUp_MonthNumber;
-- Q2: How do cancellation patterns change over time?
-- When customers are most likely to cancel their subscriptions?
SELECT
YEAR(cancel_date_time) As Cancel_Year,
MONTHNAME(cancel_date_time) As Cancel_Month,
COUNT(*) AS Cancelations
FROM
customer_product
WHERE
cancel_date_time IS NOT NULL
GROUP BY
1,2
ORDER BY
1, MIN(MONTH(cancel_date_time));
-- Q3: What is the long-term trend in customer sign-ups and cancellations over the years?
-- Determine whether the business is growing or if there are periods of decline (Net Growth Rate) ?
WITH AnnualTrends AS (
SELECT
YEAR(signup_date_time) AS Year,
COUNT(*) AS SignUps,
SUM(CASE WHEN cancel_date_time IS NOT NULL THEN 1 ELSE 0 END) AS Cancellations -- counting the number of cancellations for each year
FROM
customer_product
GROUP BY
Year
)
SELECT
Year,
SignUps,
Cancellations,
LAG(SignUps) OVER (ORDER BY Year) AS PreviousYearSignUps,
LAG(Cancellations) OVER (ORDER BY Year) AS PreviousYearCancellations,
ROUND(((SignUps - LAG(SignUps) OVER (ORDER BY Year)) / LAG(SignUps) OVER (ORDER BY Year)) * 100, 2) AS SignUpGrowthRate,
ROUND(((Cancellations - LAG(Cancellations) OVER (ORDER BY Year)) / LAG(Cancellations) OVER (ORDER BY Year)) * 100, 2) AS Cancellation_Rate,
ROUND(((SignUps - Cancellations) - (LAG(SignUps) OVER (ORDER BY Year) - LAG(Cancellations) OVER (ORDER BY Year))) /
(LAG(SignUps) OVER (ORDER BY Year) - LAG(Cancellations) OVER (ORDER BY Year)) * 100, 2) AS NetGrowthRate
FROM
AnnualTrends
ORDER BY
Year;
-- Q4: Which customer demographics (age & gender) are most likely to cancel their subscriptions?
WITH Cancellations AS ( -- Counts the number of cancellations by age and gender.
SELECT
ci.age,
ci.gender,
COUNT(c.case_id) AS Cancellation_Count
FROM
customer_cases c
JOIN
customer_info ci
ON c.customer_id = ci.customer_id
WHERE
c.reason = 'Support'
GROUP BY
1, 2
),
TotalCustomers AS ( -- Counts the total number of customers by age and gender.
SELECT
ci.age,
ci.gender,
COUNT(*) AS TotalCustomers
FROM
customer_info ci
GROUP BY
1, 2
),
CancellationRates AS (
SELECT
tc.age,
tc.gender,
COALESCE(c.Cancellation_Count, 0) AS CancellationCount,
COALESCE(tc.TotalCustomers, 1) AS TotalCustomers,
ROUND((COALESCE(c.Cancellation_Count, 0) / COALESCE(tc.TotalCustomers, 1)) * 100, 2) AS CancellationRate -- computing the cancellation rate for each demographic group.
FROM
TotalCustomers tc
LEFT JOIN
Cancellations c
ON
tc.age = c.age AND tc.gender = c.gender
)
SELECT
age,
gender,
CancellationCount,
TotalCustomers,
CancellationRate
FROM
CancellationRates
ORDER BY
age, CancellationRate DESC;
-- Q5: How do customer engagement levels differ by channel?
WITH ChannelCases AS (
SELECT channel, COUNT(*) AS case_count
FROM customer_cases
GROUP BY channel
),
TotalCases AS (
SELECT COUNT(*) AS total_count
FROM customer_cases
)
SELECT
channel,
case_count,
ROUND((case_count / total_count) * 100.0, 2) AS engagement_rate
FROM
ChannelCases,
TotalCases
ORDER BY
engagement_rate DESC;
-- Q6: What are the most common reasons for customer cases,
-- and how do they correlate with subscription cancellations?
-- Counts cases and cancellations for each reason by demographic details.
WITH CaseReasons AS (
SELECT
ci.age,
ci.gender,
c.reason,
COUNT(c.case_id) AS CaseCount,
SUM(CASE WHEN cp.cancel_date_time IS NOT NULL THEN 1 ELSE 0 END) AS Cancellations
FROM
customer_cases c
JOIN
customer_info ci ON c.customer_id = ci.customer_id
LEFT JOIN
customer_product cp ON c.customer_id = cp.customer_id AND cp.cancel_date_time IS NOT NULL
GROUP BY
ci.age, ci.gender, c.reason
),
-- Aggregates total cases and cancellations by reason.
ReasonSummary AS (
SELECT
reason,
SUM(CaseCount) AS TotalCases,
SUM(Cancellations) AS TotalCancellations
FROM
CaseReasons
GROUP BY
reason
),
-- Calculates the cancellation rate for each reason
CancellationRates AS (
SELECT
reason,
TotalCases,
TotalCancellations,
ROUND((TotalCancellations / TotalCases) * 100, 2) AS CancellationRate
FROM
ReasonSummary
)
SELECT
reason,
TotalCases,
TotalCancellations,
CancellationRate
FROM
CancellationRates
ORDER BY
CancellationRate DESC;
-- Q7: How does the billing cycle impact customer retention?
WITH BillingCycleData AS ( -- The total number of customers and the number of cancellations for each billing cycle.
SELECT
pi.billing_cycle,
COUNT(DISTINCT cp.customer_id) AS TotalCustomers,
SUM(CASE WHEN cp.cancel_date_time IS NOT NULL THEN 1 ELSE 0 END) AS Cancellations
FROM
customer_product cp
JOIN
product_info pi ON cp.product = pi.product_id
GROUP BY
pi.billing_cycle
),
RetentionRates AS ( -- The number of retained customers (those who did not cancel).
SELECT
billing_cycle,
TotalCustomers,
Cancellations,
(TotalCustomers - Cancellations) AS RetainedCustomers,
ROUND(((TotalCustomers - Cancellations) / TotalCustomers) * 100, 2) AS RetentionRate
FROM
BillingCycleData
)
SELECT
billing_cycle,
TotalCustomers,
Cancellations,
RetainedCustomers,
RetentionRate
FROM
RetentionRates
ORDER BY
RetentionRate DESC;