-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsevak_queries.sql
More file actions
393 lines (353 loc) · 15.4 KB
/
Copy pathsevak_queries.sql
File metadata and controls
393 lines (353 loc) · 15.4 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
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
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
-- ============================================================
-- SEVAK – Service Marketplace
-- IT214 DBMS Project
-- Run AFTER sevak_ddl.sql and sevak_data.sql
-- Schema: sevak
-- ============================================================
SET search_path = sevak;
-- ############################################################
-- GENERAL USER QUERIES
-- ############################################################
-- ============================================================
-- QUERY 1: Search Providers by Service Name
-- Query Text: A customer searches for "Cleaning" — find all
-- verified providers offering that service with their city,
-- rating, and price.
-- TECHNIQUES: JOIN (5 tables), ILIKE, ORDER BY
-- ============================================================
SELECT
sp.provider_id,
u.email AS provider_email,
ci.city_name,
s.service_name,
s.base_price,
sp.avg_rating,
sp.experience_years
FROM services s
JOIN provider_services ps ON s.service_id = ps.service_id
JOIN service_providers sp ON ps.provider_id = sp.provider_id
JOIN users u ON sp.user_id = u.user_id
JOIN cities ci ON sp.city_id = ci.city_id
WHERE s.service_name ILIKE '%cleaning%'
AND sp.is_active = TRUE
AND sp.verification_status = 'verified'
ORDER BY sp.avg_rating DESC NULLS LAST;
-- ============================================================
-- QUERY 2: Compare Providers for a Service in a City
-- Query Text: "I want a plumber in Mumbai — compare all
-- available providers with their rating, experience, price."
-- TECHNIQUES: JOIN (6 tables), multiple WHERE conditions
-- ============================================================
SELECT
sp.provider_id,
u.email AS provider_email,
sp.experience_years,
sp.avg_rating,
sp.custom_price AS provider_rate,
s.service_name,
s.base_price AS catalogue_price
FROM provider_services ps
JOIN service_providers sp ON ps.provider_id = sp.provider_id
JOIN services s ON ps.service_id = s.service_id
JOIN categories cat ON s.category_id = cat.category_id
JOIN users u ON sp.user_id = u.user_id
JOIN cities ci ON sp.city_id = ci.city_id
WHERE cat.category_name = 'Plumbing'
AND ci.city_name = 'Mumbai'
AND sp.is_active = TRUE
ORDER BY sp.avg_rating DESC NULLS LAST;
-- ############################################################
-- CUSTOMER QUERIES
-- ############################################################
-- ============================================================
-- QUERY 3: Booking Detail — Itemized Breakdown
-- Query Text: Customer clicks on Booking #7 to see exact
-- services, variants, quantities, and line totals.
-- TECHNIQUES: JOIN (3 tables), LEFT JOIN, computed column
-- ============================================================
SELECT
b.booking_id,
s.service_name,
sv.variant_name,
bi.quantity,
bi.unit_price,
(bi.quantity * bi.unit_price) AS line_total
FROM booking_items bi
JOIN bookings b ON bi.booking_id = b.booking_id
JOIN services s ON bi.service_id = s.service_id
LEFT JOIN service_variants sv ON bi.variant_id = sv.variant_id
WHERE b.booking_id = 7;
-- ============================================================
-- QUERY 4: Customer Spending Summary
-- Query Text: How much has Customer #1 spent in total?
-- Show total bookings, completed, cancelled, total amount.
-- TECHNIQUES: GROUP BY, CASE, COALESCE, SUM, COUNT
-- ============================================================
SELECT
cu.customer_id,
cu.name,
COUNT(b.booking_id) AS total_bookings,
COUNT(CASE WHEN b.status = 'completed' THEN 1 END) AS completed,
COUNT(CASE WHEN b.status = 'cancelled' THEN 1 END) AS cancelled,
COALESCE(SUM(CASE WHEN b.status = 'completed'
THEN b.total_amount ELSE 0 END), 0) AS total_spent
FROM customers cu
JOIN bookings b ON cu.customer_id = b.customer_id
WHERE cu.customer_id = 1
GROUP BY cu.customer_id, cu.name;
-- ============================================================
-- QUERY 5: Search Providers by City, Category, and Availability
-- Query Text: "Find me an electrician in Ahmedabad available
-- on Monday" — show all matching providers with their services.
-- TECHNIQUES: JOIN (7 tables), STRING_AGG, GROUP BY
-- ============================================================
SELECT
sp.provider_id,
u.email AS provider_email,
sp.avg_rating,
sp.experience_years,
pa.start_time,
pa.end_time,
STRING_AGG(s.service_name, ', ') AS offered_services
FROM provider_availability pa
JOIN service_providers sp ON pa.provider_id = sp.provider_id
JOIN users u ON sp.user_id = u.user_id
JOIN cities ci ON sp.city_id = ci.city_id
JOIN provider_services ps ON sp.provider_id = ps.provider_id
JOIN services s ON ps.service_id = s.service_id
JOIN categories cat ON s.category_id = cat.category_id
WHERE ci.city_name = 'Ahmedabad'
AND cat.category_name = 'Electrical'
AND pa.day_of_week = 'Monday'
AND sp.is_active = TRUE
GROUP BY sp.provider_id, u.email, sp.avg_rating,
sp.experience_years, pa.start_time, pa.end_time
ORDER BY sp.avg_rating DESC NULLS LAST;
-- ############################################################
-- SERVICE PROVIDER QUERIES
-- ############################################################
-- ============================================================
-- QUERY 6: Provider Earnings by Payment Method
-- Query Text: Show Provider #1's total earnings broken down
-- by UPI, Credit Card, and Net Banking.
-- TECHNIQUES: JOIN, SUM, CASE (pivot-style aggregation)
-- ============================================================
SELECT
COUNT(b.booking_id) AS total_jobs,
SUM(p.amount) AS total_earnings,
SUM(CASE WHEN p.payment_method = 'UPI'
THEN p.amount ELSE 0 END) AS upi_earnings,
SUM(CASE WHEN p.payment_method = 'Credit Card'
THEN p.amount ELSE 0 END) AS card_earnings,
SUM(CASE WHEN p.payment_method = 'Net Banking'
THEN p.amount ELSE 0 END) AS netbanking_earnings
FROM bookings b
JOIN payments p ON b.booking_id = p.booking_id
WHERE b.provider_id = 1
AND p.status = 'success';
-- ============================================================
-- QUERY 7: Provider Monthly Earnings Report
-- Query Text: Show Provider #1's earnings grouped by month.
-- TECHNIQUES: DATE_TRUNC, GROUP BY, SUM, COUNT
-- ============================================================
SELECT
DATE_TRUNC('month', b.scheduled_date) AS month,
COUNT(b.booking_id) AS jobs_completed,
SUM(p.amount) AS monthly_earnings
FROM bookings b
JOIN payments p ON b.booking_id = p.booking_id
WHERE b.provider_id = 1
AND b.status = 'completed'
AND p.status = 'success'
GROUP BY DATE_TRUNC('month', b.scheduled_date)
ORDER BY month DESC;
-- ============================================================
-- QUERY 8: Provider Rating vs City Average
-- Query Text: Is Provider #1's rating above or below the
-- average of all providers in their city?
-- TECHNIQUES: Derived table (subquery in FROM), CASE, ROUND
-- ============================================================
SELECT
sp.provider_id,
u.email AS provider_email,
ci.city_name,
sp.avg_rating AS my_rating,
city_avg.city_average,
CASE
WHEN sp.avg_rating >= city_avg.city_average
THEN 'Above Average'
ELSE 'Below Average'
END AS comparison
FROM service_providers sp
JOIN users u ON sp.user_id = u.user_id
JOIN cities ci ON sp.city_id = ci.city_id
JOIN (
SELECT city_id, ROUND(AVG(avg_rating), 2) AS city_average
FROM service_providers
WHERE avg_rating IS NOT NULL
GROUP BY city_id
) city_avg ON sp.city_id = city_avg.city_id
WHERE sp.provider_id = 1;
-- ############################################################
-- ADMIN / PLATFORM QUERIES
-- ############################################################
-- ============================================================
-- QUERY 9: Revenue by Service Category
-- Query Text: Which service categories generate the most
-- revenue from completed bookings?
-- TECHNIQUES: JOIN (4 tables), GROUP BY, SUM, COUNT DISTINCT
-- ============================================================
SELECT
cat.category_name,
COUNT(DISTINCT b.booking_id) AS total_bookings,
SUM(bi.unit_price * bi.quantity) AS total_revenue
FROM categories cat
JOIN services s ON cat.category_id = s.category_id
JOIN booking_items bi ON s.service_id = bi.service_id
JOIN bookings b ON bi.booking_id = b.booking_id
WHERE b.status = 'completed'
GROUP BY cat.category_name
ORDER BY total_revenue DESC;
-- ============================================================
-- QUERY 10: Provider Performance Leaderboard
-- Query Text: Rank all providers by total revenue earned,
-- showing their city, rating, and number of completed jobs.
-- TECHNIQUES: RANK() OVER (Window Function), JOIN (5 tables)
-- ============================================================
SELECT
sp.provider_id,
u.email AS provider_email,
ci.city_name,
sp.avg_rating,
COUNT(b.booking_id) AS jobs_completed,
SUM(p.amount) AS total_revenue,
RANK() OVER (ORDER BY SUM(p.amount) DESC NULLS LAST) AS revenue_rank
FROM service_providers sp
JOIN users u ON sp.user_id = u.user_id
JOIN cities ci ON sp.city_id = ci.city_id
JOIN bookings b ON sp.provider_id = b.provider_id
JOIN payments p ON b.booking_id = p.booking_id
WHERE b.status = 'completed'
AND p.status = 'success'
GROUP BY sp.provider_id, u.email, ci.city_name, sp.avg_rating
ORDER BY revenue_rank;
-- ============================================================
-- QUERY 11: Areas With the Highest Complaint Frequency
-- Query Text: Which areas/localities have the most complaints?
-- Help admins identify problem zones.
-- TECHNIQUES: JOIN (5 tables), GROUP BY, HAVING, COUNT
-- ============================================================
SELECT
ci.city_name,
ar.area_name,
ar.pincode,
COUNT(cmp.complaint_id) AS complaint_count
FROM complaints cmp
JOIN bookings b ON cmp.booking_id = b.booking_id
JOIN locations loc ON b.location_id = loc.location_id
JOIN areas ar ON loc.area_id = ar.area_id
JOIN cities ci ON ar.city_id = ci.city_id
GROUP BY ci.city_name, ar.area_name, ar.pincode
HAVING COUNT(cmp.complaint_id) >= 1
ORDER BY complaint_count DESC;
-- ============================================================
-- QUERY 12: Coupon Usage and Effectiveness Report
-- Query Text: How many times has each coupon been used?
-- What is the total discount given and remaining uses?
-- TECHNIQUES: LEFT JOIN, GROUP BY, SUM, CASE
-- ============================================================
SELECT
co.code,
co.discount_type,
co.discount_value,
co.usage_limit,
COUNT(b.booking_id) AS times_used,
(co.usage_limit - COUNT(b.booking_id)) AS remaining_uses,
SUM(CASE
WHEN co.discount_type = 'flat' THEN co.discount_value
WHEN co.discount_type = 'percentage' THEN ROUND(b.total_amount * co.discount_value / 100, 2)
ELSE 0
END) AS total_discount_given
FROM coupons co
LEFT JOIN bookings b ON co.coupon_id = b.coupon_id
GROUP BY co.coupon_id, co.code, co.discount_type, co.discount_value, co.usage_limit
ORDER BY times_used DESC;
-- ============================================================
-- QUERY 13: Customers Who Never Placed a Booking
-- Query Text: Find registered customers who have never
-- placed a single booking — targets for marketing.
-- TECHNIQUES: LEFT JOIN, IS NULL (Anti-join pattern)
-- ============================================================
SELECT
cu.customer_id,
cu.name,
cu.phone,
u.email,
u.status AS account_status
FROM customers cu
JOIN users u ON cu.user_id = u.user_id
LEFT JOIN bookings b ON cu.customer_id = b.customer_id
WHERE b.booking_id IS NULL
ORDER BY cu.name;
-- ============================================================
-- QUERY 14: Booking Lifecycle — Time Between Status Changes
-- Query Text: Measure how long it takes for bookings to move
-- from pending → confirmed → in_progress → completed.
-- TECHNIQUES: Self-JOIN, Correlated Subquery, INTERVAL
-- ============================================================
SELECT
bsl1.booking_id,
bsl1.status AS from_status,
bsl2.status AS to_status,
(bsl2.log_time - bsl1.log_time) AS time_taken
FROM booking_status_log bsl1
JOIN booking_status_log bsl2
ON bsl1.booking_id = bsl2.booking_id
AND bsl2.log_time = (
SELECT MIN(bsl3.log_time)
FROM booking_status_log bsl3
WHERE bsl3.booking_id = bsl1.booking_id
AND bsl3.log_time > bsl1.log_time
)
ORDER BY bsl1.booking_id, bsl1.log_time;
-- ============================================================
-- QUERY 15: Full Booking Master View — 10+ Table Mega Join
-- Query Text: The ultimate admin report combining every data
-- point: customer, provider, city, area, service, category,
-- items, payment status, review rating, and coupon used.
-- TECHNIQUES: JOIN (10+ tables), LEFT JOIN, COALESCE
-- ============================================================
SELECT
b.booking_id,
cu.name AS customer_name,
u_prov.email AS provider_email,
ci.city_name,
ar.area_name,
loc.street,
s.service_name,
cat.category_name,
bi.quantity,
bi.unit_price,
b.total_amount,
b.status AS booking_status,
b.scheduled_date,
COALESCE(p.status, 'no payment') AS payment_status,
COALESCE(pr.rating::TEXT, '-') AS provider_rating,
COALESCE(co.code, 'none') AS coupon_used
FROM bookings b
JOIN customers cu ON b.customer_id = cu.customer_id
JOIN service_providers sp ON b.provider_id = sp.provider_id
JOIN users u_prov ON sp.user_id = u_prov.user_id
JOIN locations loc ON b.location_id = loc.location_id
JOIN areas ar ON loc.area_id = ar.area_id
JOIN cities ci ON ar.city_id = ci.city_id
JOIN booking_items bi ON b.booking_id = bi.booking_id
JOIN services s ON bi.service_id = s.service_id
JOIN categories cat ON s.category_id = cat.category_id
LEFT JOIN payments p ON b.booking_id = p.booking_id
LEFT JOIN provider_reviews pr ON b.booking_id = pr.booking_id
LEFT JOIN coupons co ON b.coupon_id = co.coupon_id
ORDER BY b.booking_id, bi.item_no;
-- ============================================================
-- END OF QUERIES
-- ============================================================