-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathproject.sql.sqbpro
321 lines (264 loc) · 12 KB
/
project.sql.sqbpro
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
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
<?xml version="1.0" encoding="UTF-8"?><sqlb_project><db path="C:/Users/user/Downloads/stores.db" readonly="0" foreign_keys="1" case_sensitive_like="0" temp_store="0" wal_autocheckpoint="1000" synchronous="2"/><attached/><window><main_tabs open="structure browser pragmas query" current="3"/></window><tab_structure><column_width id="0" width="300"/><column_width id="1" width="0"/><column_width id="2" width="125"/><column_width id="3" width="4975"/><column_width id="4" width="0"/><expanded_item id="0" parent="1"/><expanded_item id="1" parent="1"/><expanded_item id="2" parent="1"/><expanded_item id="3" parent="1"/></tab_structure><tab_browse><current_table name="4,9:maincustomers"/><default_encoding codec=""/><browse_table_settings><table schema="main" name="customers" show_row_id="0" encoding="" plot_x_axis="" unlock_view_pk="_rowid_"><sort/><column_widths><column index="1" value="158"/><column index="2" value="262"/><column index="3" value="159"/><column index="4" value="161"/><column index="5" value="152"/><column index="6" value="242"/><column index="7" value="188"/><column index="8" value="145"/><column index="9" value="101"/><column index="10" value="106"/><column index="11" value="104"/><column index="12" value="237"/><column index="13" value="102"/></column_widths><filter_values/><conditional_formats/><row_id_formats/><display_formats/><hidden_columns/><plot_y_axes/><global_filter/></table><table schema="main" name="products" show_row_id="0" encoding="" plot_x_axis="" unlock_view_pk="_rowid_"><sort/><column_widths><column index="1" value="120"/><column index="2" value="300"/><column index="3" value="137"/><column index="4" value="122"/><column index="5" value="200"/><column index="6" value="300"/><column index="7" value="149"/><column index="8" value="84"/><column index="9" value="59"/></column_widths><filter_values/><conditional_formats/><row_id_formats/><display_formats/><hidden_columns/><plot_y_axes/><global_filter/></table></browse_table_settings></tab_browse><tab_sql><sql name="SQL 1">--Check data types & other table information
PRAGMA table_info(customers);
--Select each table name as a string
SELECT name AS table_name
FROM sqlite_schema
WHERE type='table';
--Count the number of attributes per table
SELECT COUNT(*) AS number_of_attributes, 'customers' AS name
FROM pragma_table_info('customers')
UNION ALL
SELECT COUNT(*) AS number_of_attributes, 'employees' AS name
FROM pragma_table_info('employees')
UNION ALL
SELECT COUNT(*) AS number_of_attributes, 'offices' AS name
FROM pragma_table_info('offices')
UNION ALL
SELECT COUNT(*) AS number_of_attributes, 'orderdetails' AS name
FROM pragma_table_info('orderdetails')
UNION ALL
SELECT COUNT(*) AS number_of_attributes, 'orders' AS name
FROM pragma_table_info('orders')
UNION ALL
SELECT COUNT(*) AS number_of_attributes, 'payments' AS name
FROM pragma_table_info('payments')
UNION ALL
SELECT COUNT(*) AS number_of_attributes, 'productlines' AS name
FROM pragma_table_info('productlines')
UNION ALL
SELECT COUNT(*) AS number_of_attributes, 'products' AS name
FROM pragma_table_info('products');
--Number of rows in each TABLE
SELECT COUNT(*) AS number_of_rows, 'customers' AS name
FROM customers
UNION ALL
SELECT COUNT(*) AS number_of_rows, 'employees' AS name
FROM employees
UNION ALL
SELECT COUNT(*) AS number_of_rows, 'offices' AS name
FROM offices
UNION ALL
SELECT COUNT(*) AS number_of_rows, 'orderdetails' AS name
FROM orderdetails
UNION ALL
SELECT COUNT(*) AS number_of_rows, 'orders' AS name
FROM orders
UNION ALL
SELECT COUNT(*) AS number_of_rows, 'payments' AS name
FROM payments
UNION ALL
SELECT COUNT(*) AS number_of_rows, 'productlines' AS name
FROM productlines
UNION ALL
SELECT COUNT(*) AS number_of_rows, 'products' AS name
FROM products;
--Combine the columns
WITH
table_names AS (
SELECT name AS table_name
FROM sqlite_schema
WHERE type='table'
),
attribute_no AS (
SELECT COUNT(*) AS number_of_attributes, 'customers' AS name
FROM pragma_table_info('customers')
UNION ALL
SELECT COUNT(*) AS number_of_attributes, 'employees' AS name
FROM pragma_table_info('employees')
UNION ALL
SELECT COUNT(*) AS number_of_attributes, 'offices' AS name
FROM pragma_table_info('offices')
UNION ALL
SELECT COUNT(*) AS number_of_attributes, 'orderdetails' AS name
FROM pragma_table_info('orderdetails')
UNION ALL
SELECT COUNT(*) AS number_of_attributes, 'orders' AS name
FROM pragma_table_info('orders')
UNION ALL
SELECT COUNT(*) AS number_of_attributes, 'payments' AS name
FROM pragma_table_info('payments')
UNION ALL
SELECT COUNT(*) AS number_of_attributes, 'productlines' AS name
FROM pragma_table_info('productlines')
UNION ALL
SELECT COUNT(*) AS number_of_attributes, 'products' AS name
FROM pragma_table_info('products')
),
row_numbers AS (
SELECT COUNT(*) AS number_of_rows, 'customers' AS name
FROM customers
UNION ALL
SELECT COUNT(*) AS number_of_rows, 'employees' AS name
FROM employees
UNION ALL
SELECT COUNT(*) AS number_of_rows, 'offices' AS name
FROM offices
UNION ALL
SELECT COUNT(*) AS number_of_rows, 'orderdetails' AS name
FROM orderdetails
UNION ALL
SELECT COUNT(*) AS number_of_rows, 'orders' AS name
FROM orders
UNION ALL
SELECT COUNT(*) AS number_of_rows, 'payments' AS name
FROM payments
UNION ALL
SELECT COUNT(*) AS number_of_rows, 'productlines' AS name
FROM productlines
UNION ALL
SELECT COUNT(*) AS number_of_rows, 'products' AS name
FROM products
)
SELECT tn.table_name, an.number_of_attributes, number_of_rows
FROM table_names tn
JOIN attribute_no AS an ON tn.table_name = an.name
JOIN row_numbers AS rn ON tn.table_name = rn.name
--Question 1: Which products should we order more/less of?
--We'll consider low stock(i.e. product in demand) and product performance
--a)product performance=SUM(quantityOrdered × priceEach)
SELECT p.productCode,
od.quantityOrdered, od.priceEach,
SUM(od.quantityOrdered * od.priceEach) AS revenue
FROM orderdetails AS od
LEFT JOIN products AS p ON p.productCode = od.productCode
GROUP BY p.productCode
ORDER BY revenue DESC
LIMIT 10
b) low stock = SUM(quantityOrdered)/quantityInStock
SELECT productCode,
ROUND(SUM(quantityOrdered) * 1.0/(SELECT quantityInStock
FROM products p
WHERE od.productCode = p.productCode),2) AS low_stock
FROM orderdetails od
GROUP BY productCode
ORDER BY low_stock DESC
LIMIT 10;
--Combine the product performance & low_stock queries using CTE
WITH
lowStock AS (
SELECT productCode,
ROUND(SUM(quantityOrdered) * 1.0/(SELECT quantityInStock
FROM products p
WHERE od.productCode = p.productCode),2) AS low_stock
FROM orderdetails od
GROUP BY productCode
ORDER BY low_stock
LIMIT 10
),
productPerformance AS (
SELECT p.productCode,
od.quantityOrdered, od.priceEach,
SUM(od.quantityOrdered * od.priceEach) AS revenue
FROM orderdetails AS od
LEFT JOIN products AS p ON p.productCode = od.productCode
GROUP BY p.productCode
ORDER BY revenue DESC
)
SELECT p.productCode, p.productName, p.productLine
FROM productPerformance pp
JOIN products p ON p.productCode = pp.productCode
WHERE pp.productCode IN (SELECT productCode
FROM lowStock)
ORDER BY revenue DESC
LIMIT 10
--Question 2: How should we match marketing & communication strategies to customer behavior?
-- We want to find the VIP customers & less engaged customers
--Ceteris paribus, VIP customers bring in the most profit for the store while Less-engaged customers bring in less profit
SELECT o.customerNumber,
od.quantityOrdered, od.priceEach,
p.buyPrice,
SUM(quantityOrdered * (priceEach - buyPrice)) AS profit --sums profit per customer
FROM orders o
LEFT JOIN orderdetails od ON o.orderNumber = od.orderNumber
LEFT JOIN products p ON p.productCode = od.productCode
GROUP BY o.customerNumber
ORDER BY profit
--Finding top5 VIP customers
WITH
VIPtop5 AS (
SELECT o.customerNumber,
od.quantityOrdered, od.priceEach,
p.buyPrice,
SUM(quantityOrdered * (priceEach - buyPrice)) AS profit
FROM orders o
LEFT JOIN orderdetails od ON o.orderNumber = od.orderNumber
LEFT JOIN products p ON p.productCode = od.productCode
GROUP BY o.customerNumber
)
SELECT contactLastName, contactFirstName, city, country, customerNumber
FROM customers
WHERE customerNumber IN (SELECT customerNumber
FROM VIPtop5
ORDER BY profit DESC
LIMIT 5)
--Finding top5 less engaged customers
WITH
LessEngaged5 AS (
SELECT o.customerNumber,
od.quantityOrdered, od.priceEach,
p.buyPrice,
SUM(quantityOrdered * (priceEach - buyPrice)) AS profit
FROM orders o
LEFT JOIN orderdetails od ON o.orderNumber = od.orderNumber
LEFT JOIN products p ON p.productCode = od.productCode
GROUP BY o.customerNumber
)
SELECT contactLastName, contactFirstName, city, country, customerNumber
FROM customers
WHERE customerNumber IN (SELECT customerNumber
FROM LessEngaged5
ORDER BY profit
LIMIT 5)
-- Question 3: How much can we spend on acquiring new customers?
--To begin with, let's find the number of new customers arriving each month.
--That way we can check if it's worth spending money on acquiring new customers. This query helps to find these numbers
WITH
payment_with_year_month_table AS (
SELECT *,
CAST(SUBSTR(paymentDate, 1,4) AS INTEGER)*100 + CAST(SUBSTR(paymentDate, 6,7) AS INTEGER) AS year_month
FROM payments p
),
customers_by_month_table AS (
SELECT p1.year_month, COUNT(*) AS number_of_customers, SUM(p1.amount) AS total
FROM payment_with_year_month_table p1
GROUP BY p1.year_month
),
new_customers_by_month_table AS (
SELECT p1.year_month,
COUNT(*) AS number_of_new_customers,
SUM(p1.amount) AS new_customer_total,
(SELECT number_of_customers
FROM customers_by_month_table c
WHERE c.year_month = p1.year_month) AS number_of_customers,
(SELECT total
FROM customers_by_month_table c
WHERE c.year_month = p1.year_month) AS total
FROM payment_with_year_month_table p1
WHERE p1.customerNumber NOT IN (SELECT customerNumber
FROM payment_with_year_month_table p2
WHERE p2.year_month < p1.year_month)
GROUP BY p1.year_month
)
SELECT year_month,
ROUND(number_of_new_customers*100/number_of_customers,1) AS number_of_new_customers_props,
ROUND(new_customer_total*100/total,1) AS new_customers_total_props
FROM new_customers_by_month_table;
--To determine how much money we can spend acquiring new customers, we can compute the Customer Lifetime Value (LTV).
--It represents the average amount of money a customer generates.
--We can then determine how much we can spend on marketing.
WITH
profit_per_customer AS (
SELECT o.customerNumber,
od.quantityOrdered, od.priceEach,
p.buyPrice,
SUM(quantityOrdered * (priceEach - buyPrice)) AS profit --sums profit per customer
FROM orders o
LEFT JOIN orderdetails od ON o.orderNumber = od.orderNumber
LEFT JOIN products p ON p.productCode = od.productCode
GROUP BY o.customerNumber
ORDER BY profit
)
SELECT AVG(profit)
FROM profit_per_customer
-- We can use LTV to predict our future profit.
--So, if we get ten new customers next month, we'll earn 390,395 dollars, and we can decide based on this prediction how much we can spend on acquiring new customers.</sql><current_tab id="0"/></tab_sql></sqlb_project>