-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDanny's Dinner SQL challenge v1.sql
More file actions
240 lines (204 loc) · 6.41 KB
/
Danny's Dinner SQL challenge v1.sql
File metadata and controls
240 lines (204 loc) · 6.41 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
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
-- Creating danny's_diner database schema
CREATE SCHEMA dannys_diner;
GO
/*
sales table has customer_id level purchases with a corresponding order_date and product_id
information for when and what menu items were ordered.
*/
CREATE TABLE sales (
"customer_id" VARCHAR(1),
"order_date" DATE,
"product_id" INTEGER
);
INSERT INTO sales
("customer_id", "order_date", "product_id")
VALUES
('A', '2021-01-01', '1'),
('A', '2021-01-01', '2'),
('A', '2021-01-07', '2'),
('A', '2021-01-10', '3'),
('A', '2021-01-11', '3'),
('A', '2021-01-11', '3'),
('B', '2021-01-01', '2'),
('B', '2021-01-02', '2'),
('B', '2021-01-04', '1'),
('B', '2021-01-11', '1'),
('B', '2021-01-16', '3'),
('B', '2021-02-01', '3'),
('C', '2021-01-01', '3'),
('C', '2021-01-01', '3'),
('C', '2021-01-07', '3');
--menu table maps the product_id to the actual product_name and price of each menu item.
CREATE TABLE menu (
"product_id" INTEGER,
"product_name" VARCHAR(5),
"price" INTEGER
);
INSERT INTO menu
("product_id", "product_name", "price")
VALUES
('1', 'sushi', '10'),
('2', 'curry', '15'),
('3', 'ramen', '12');
/*
members table captures the join_date when a customer_id joined the beta version
of the Danny's Diner loyalty program.
*/
CREATE TABLE members (
"customer_id" VARCHAR(1),
"join_date" DATE
);
INSERT INTO members
("customer_id", "join_date")
VALUES
('A', '2021-01-07'),
('B', '2021-01-09');
-- total amount each customer spent at the restaurant
Select s.customer_id, SUM(m.price)
From sales s
Join menu m
ON s.product_id = m.product_id
Group by s.customer_id
-- days each customer has visited the restaurant
Select customer_id, COUNT(DISTINCT order_date) AS days_visited
From sales
Group by customer_id
-- the first item from the menu purchased by each customer
WITH ranked_item as (
Select s.customer_id, s.order_date ,m.product_name,
DENSE_RANK() OVER (PARTITION BY s.customer_id ORDER BY s.order_date) AS ranked
From sales s
Join menu m
ON s.product_id = m.product_id
)
Select customer_id, product_name
From ranked_item
Where ranked = '1'
Group by customer_id, product_name
-- the most purchased item on the menu and the times it was purchased by all customers
Select TOP 1
m.product_name, COUNT(s.product_id) as count_product
From menu m
Join sales s
ON m.product_id = s.product_id
Group by m.product_name
Order by count_product DESC
/* item that was most popular for each customer
rank the number of orders for each item by DESC order for each customer
*/
WITH most_popular AS
(
Select s.customer_id, m.product_name, COUNT(m.product_id) AS product_count,
DENSE_RANK() OVER (PARTITION BY s.customer_id ORDER BY COUNT(m.product_id) DESC) AS ranked
From sales s
Join menu m
ON s.product_id = m.product_id
Group by s.customer_id, m.product_name
)
Select customer_id, product_name,product_count
From most_popular
Where ranked = '1'
-- item purchased first by the customer after becoming a member
WITH first_item AS
(
Select s.customer_id, m.product_name, s.order_date, e.join_date,
DENSE_RANK() OVER (PARTITION BY s.customer_id ORDER BY s.order_date) AS ranked
From sales s
Join menu m
ON m.product_id = s.product_id
Join members e
ON s.customer_id = e.customer_id
Where s.order_date >= e.join_date
)
Select customer_id, product_name
From first_item
Where ranked = '1'
--item purchased just before becoming a member
WITH before_membership AS
(
Select s.customer_id, m.product_name, s.order_date, e.join_date,
DENSE_RANK() OVER (PARTITION BY s.customer_id ORDER BY s.order_date) AS ranked
From sales s
Join menu m
ON m.product_id = s.product_id
Join members e
ON s.customer_id = e.customer_id
Where s.order_date < e.join_date
)
Select customer_id, product_name
From before_membership
Where ranked = '1'
-- total items and amount spent for each member before they became a member
Select s.customer_id, COUNT( DISTINCT s.product_id) AS count_product ,SUM (m.price) AS total_sales
From sales s
Join menu m
ON m.product_id = s.product_id
Join members e
ON s.customer_id = e.customer_id
Where s.order_date < e.join_date
Group by s.customer_id
-- total points for customers
WITH cust_points AS
(
Select s.customer_id, m.product_id,
CASE WHEN m.product_id = 1 THEN m.price * 20
ELSE m.price * 10
END points
From sales s
Join menu m
ON s.product_id = m.product_id
)
Select customer_id, SUM(points) AS total_points
From cust_points
Group by customer_id
-- points for customer A & B at the end of January
-- create a CTE to get the interval dates and last day dates
WITH Dates AS
(Select *,
DATEADD(DAY, 6, join_date) AS interval_dates,
EOMONTH('2021-01-31') AS last_day
From members)
Select d.customer_id, d.join_date, d.interval_dates, d.last_day,
m.product_name, m.price, s.order_date,
SUM(CASE WHEN m.product_name = 'sushi' THEN m.price * 2 * 10
WHEN s.order_date BETWEEN d.join_date AND d.interval_dates THEN m.price * 2 * 10
ELSE m.price * 10
END) AS total_points
From sales s
Join Dates d
ON s.customer_id = d.customer_id
Join menu m
ON s.product_id = m.product_id
Where s.order_date < d.interval_dates
Group by d.customer_id, d.join_date, d.interval_dates, d.last_day,
m.product_name, m.price, s.order_date
-- creating new table with customer_id, order_date, product_name, price an new column as member
Select s.customer_id, s.order_date, m.product_name, m.price,
CASE WHEN s.order_date < e.join_date THEN 'N'
WHEN s.order_date >= e.join_date THEN 'Y'
ELSE 'N'
END member
From sales s
Left Join menu m
ON s.product_id = m.product_id
Left Join members e
ON s.customer_id = e.customer_id
-- ranking of customer products
WITH product_ranking AS
(
Select s.customer_id, s.order_date, m.product_name, m.price,
CASE WHEN s.order_date < e.join_date THEN 'N'
WHEN s.order_date >= e.join_date THEN 'Y'
ELSE 'N'
END member
From sales s
Left Join menu m
ON s.product_id = m.product_id
Left Join members e
ON s.customer_id = e.customer_id
)
Select *,
CASE WHEN member = 'N' THEN NULL
ELSE
DENSE_RANK() OVER (PARTITION BY customer_id, member ORDER BY order_date)END AS ranking
From product_ranking