QueryOptimization: MajStore_Views_Indexes.sql

File MajStore_Views_Indexes.sql, 13.4 KB (added by 231049, 9 days ago)
Line 
1-- View 1
2create or replace view vw_worker_premium_analytics as
3select w.worker_id,
4 date_trunc('month', py.payment_date) as month,
5 pp.plan_id, pp.name AS plan_name,
6 COUNT(pw.premium_id) filter ( where ps.status_name = 'Completed' ) as total_plans_bought,
7 SUM(py.amount) filter ( where ps.status_name = 'Completed' ) as total_spent,
8 MIN(pw.start_date) as first_plan_start,
9 MAX(pw.end_date) as last_plan_end
10from Premium_Worker pw
11 join Worker w on w.worker_id = pw.worker_id
12 join Payment py on py.payment_id = pw.payment_id
13 join Payment_Status ps on ps.status_id = py.payment_status
14 join Worker_Method wm on wm.worker_method_id = py.worker_method_id
15 join Premium_Plan pp on pp.plan_id = pw.plan_id
16group by w.worker_id, date_trunc('month', py.payment_date), pp.plan_id, pp.name;
17
18-- test
19select * from vw_worker_premium_analytics
20where worker_id = 6630371;
21
22
23
24
25-- View 2
26create or replace view vw_owner_payment_analytics_dashboard as
27with daily_stats as (
28 select
29 date_trunc('day', py.payment_date) as day,
30 pm.method_id,
31 pm.method_name,
32 pm.tax,
33 COUNT(py.payment_id) as n_per_method_per_day,
34 SUM(py.amount) as t_per_method_day
35 from Payment py
36 join Payment_Status ps on ps.status_id = py.payment_status
37 join Worker_Method wm on wm.worker_method_id = py.worker_method_id
38 join Payment_Method pm on pm.method_id = wm.method_id
39 where ps.status_name = 'Completed'
40 group by date_trunc('day', py.payment_date), pm.method_id, pm.method_name, pm.tax
41), ranked as (
42 select *,
43 SUM(n_per_method_per_day) over (partition by day) as t_n_payments_day,
44 SUM(t_per_method_day) over (partition by day) as t_amount_day,
45 SUM(t_per_method_day * tax) OVER (partition by day) as t_tax_day,
46 ROW_NUMBER() over (partition by day ORDER BY n_per_method_per_day desc) as rn
47 from daily_stats
48)
49select
50 day,
51 t_amount_day as total_earned,
52 t_n_payments_day as total_transactions,
53 ROUND(t_tax_day::NUMERIC, 2) as total_tax_collected,
54 method_id as most_used_method_id,
55 method_name as most_used_method,
56 ROUND((n_per_method_per_day::NUMERIC / NULLIF(t_n_payments_day, 0)) * 100, 2) as most_used_method_pct
57from ranked
58where rn = 1;
59
60-- test
61select * from vw_owner_payment_analytics_dashboard
62where day = '2024-11-17 00:00:00.000';
63
64
65
66
67
68
69-- View 3
70create or replace view vw_review_analytics as
71select
72 ws.worker_id,
73 u.username,
74 s.specialty_name,
75 ws.specialty_id,
76 (
77 select avg(r.grade)
78 from Review r
79 where r.worker_specialty_id = ws.worker_specialty_id
80 ) as avg_grade,
81 (
82 select count(*)
83 from Review r
84 where r.worker_specialty_id = ws.worker_specialty_id
85 ) as total_reviews,
86 (
87 select count(*)
88 from Review_Comment rc
89 where rc.review_id in (
90 select r.review_id
91 from Review r
92 where r.worker_specialty_id = ws.worker_specialty_id
93 )
94 ) as total_comments,
95 (
96 select count(*)
97 from Review r
98 where r.worker_specialty_id = ws.worker_specialty_id
99 and r.grade = 1
100 ) as one_star,
101 (
102 select count(*)
103 from Review r
104 where r.worker_specialty_id = ws.worker_specialty_id
105 and r.grade = 2
106 ) as two_star,
107 (
108 select count(*)
109 from Review r
110 where r.worker_specialty_id = ws.worker_specialty_id
111 and r.grade = 3
112 ) as three_star,
113 (
114 select count(*)
115 from Review r
116 where r.worker_specialty_id = ws.worker_specialty_id
117 and r.grade = 4
118 ) as four_star,
119 (
120 select count(*)
121 from Review r
122 where r.worker_specialty_id = ws.worker_specialty_id
123 and r.grade = 5
124 ) as five_star
125from Worker_Specialty ws
126 join specialty s on ws.specialty_id = s.specialty_id
127 join worker w on ws.worker_id = w.worker_id
128 join "User" u on u.user_id = w.user_id;
129
130-- test
131select * from vw_review_analytics
132where worker_id = 6630378;
133
134
135
136
137
138
139
140-- View 4
141create or replace view vw_worker_aggregate as
142select
143 w.worker_id,
144 u.first_name,
145 u.last_name,
146 u.username,
147 count(distinct a.application_id) as total_applications,
148 count(distinct a.application_id) filter (where apps.status_name = 'Accepted') as accepted_applications,
149 count(distinct a.application_id) filter (where apps.status_name = 'Rejected') as rejected_applications,
150
151 round(count(distinct a.application_id) filter (
152 where apps.status_name = 'Accepted'
153 )::numeric / count(distinct a.application_id)*100,2) as accepted_percentage,
154
155 round(count(distinct a.application_id) filter (
156 where apps.status_name = 'Rejected'
157 )::numeric / count(distinct a.application_id)*100,2) as rejected_percentage,
158
159 count(distinct a.application_id) filter (
160 where apps.status_name = 'Accepted'and ps.status_name = 'Completed'
161 ) as completed_jobs
162
163from worker w
164 join "User" u on u.user_id= w.user_id
165 join application a on a.worker_id= w.worker_id
166 join application_status apps on apps.status_id = a.status_id
167 join post po on po.post_id = a.post_id
168 join post_status ps on ps.status_id = po.status_id
169group by w.worker_id, u.first_name, u.last_name, u.username;
170
171-- test
172select *
173from vw_worker_aggregate
174where worker_id = 6630378;
175
176insert into application (message, needed_time, expected_price, created_at, worker_id, post_id, status_id)
177 values ('Adding a new application', '01:00:00', 5000, '2023-06-22 14:00:03.945', 6722966, 4137859, 3)
178update Application set expected_price=5509 where application_id = 8308242;
179
180-- index
181create index idx_application_worker_id on application(worker_id);
182
183
184
185
186
187-- View 5
188
189create materialized view vw_app_aggregate as
190select
191 count(distinct u.user_id) as total_users,
192 count(distinct p.post_id) as total_posts,
193 count(distinct p.post_id) filter (where ps.status_name = 'Active') as active_posts,
194 count(distinct p.post_id) filter (where ps.status_name = 'Completed') as completed_posts,
195 count(distinct p.post_id) filter (where ps.status_name = 'Deleted') as deleted_posts,
196 round(count(distinct p.post_id) filter (where ps.status_name = 'Active')::numeric
197 / count(distinct p.post_id) * 100, 2) as active_post_pct,
198 count(distinct a.application_id) as total_applications,
199 (select max(p2.created_at) from post p2) as latest_post_date
200from "User" u
201 left join post p on p.user_id = u.user_id
202 left join post_status ps on ps.status_id = p.status_id
203 left join application a on a.post_id = p.post_id;
204
205-- test
206select *
207from vw_app_aggregate;
208
209insert into post (title, description, created_at, user_id, location_id, status_id)
210 values ('Needing a plumber', 'The bath is leaking', '2024-03-07 18:52:55.693', 503189, 9199, 2)
211
212update post
213set description = 'The bath is leaking from the bottom'
214where user_id = 503189 and created_at = '2024-03-07 18:52:55.693'
215
216
217
218
219
220
221-- View 6
222create or replace view vw_location_aggregate as
223select
224 l.location_id,
225 l.city,
226 l.region,
227 count(distinct p.post_id) as total_posts,
228 count(distinct p.post_id) filter (where ps.status_name = 'Active') as active_posts,
229 count(distinct p.post_id) filter (where ps.status_name = 'Completed') as completed_posts,
230 count(distinct w.worker_id) as total_workers,
231 count(distinct w.worker_id) filter (where w.works_remote = true) as remote_workers
232from location l
233 left join post p on p.location_id= l.location_id
234 left join post_status ps on ps.status_id = p.status_id
235 left join worker w on w.location_id = l.location_id
236group by l.location_id, l.city, l.region;
237
238--test
239select *
240from vw_location_aggregate
241where location_id = 7;
242
243-- index
244create index idx_post_location on Post(location_id);
245
246
247
248
249
250
251
252-- View 7
253create or replace view vw_post_full_details as
254select p.post_id, p.title, p.description, p.created_at,
255 ps.status_name,
256 u.user_id, u.first_name, u.last_name, u.username,
257 l.city, l.region, l.address,
258
259 array_agg(distinct s.specialty_name) as specialties,
260 array_agg(distinct pi.image_id) as image_ids,
261 count(distinct a.application_id) as total_applications,
262 count(distinct a.application_id) filter ( where apps.status_name = 'Accepted') as accepted_applications,
263 count(distinct a.application_id) filter (where apps.status_name = 'Rejected') as rejected_applications,
264 round(avg(a.expected_price)::numeric, 2) as avg_expected_price,
265 min(a.expected_price) as min_expected_price,
266 max(a.expected_price) as max_expected_price
267
268from post p
269 join post_status ps on ps.status_id = p.status_id
270 join "User" u on u.user_id = p.user_id
271 join location l on l.location_id = p.location_id
272 join post_specialty psp on psp.post_id = p.post_id
273 join specialty s on s.specialty_id = psp.specialty_id
274 join post_image pi on pi.post_id = p.post_id
275 join application a on a.post_id = p.post_id
276 join application_status apps on apps.status_id = a.status_id
277
278group by p.post_id, p.title, p.description, p.created_at,
279 ps.status_name,
280 u.user_id, u.first_name, u.last_name, u.username,
281 l.city, l.region, l.address;
282
283-- test
284select *
285from vw_post_full_details
286where post_id = 1539670;
287
288insert into Post_Specialty(post_id, specialty_id)
289 values (919803, 1);
290
291insert into Post_Image(image_file, post_id)
292 values ('x48562878a554caab5dd263b0e66a3ff246d272d4988137609211e640faddb168967b0ae78a446bebbd26b6c6386d548e8f38474363c68595cf054f3a212ebae567640dc8227c9fd60a17bb3c59226226ba83612c47e89d3c02c68350a1f025a4d1d8d1356894e72614763be27b43f84208d1f08e07ff92e9b6f524e8da169885b41621dbdd1438376bb0215285e1ff3817ffce1dbe2eb04d3a8d9ba5078f853e3b7eb87d9343b0c0741c788e669a2b16d5d616675c16c53798dbfee28139377bc15f99f7fe10e382162519eda8f81a7301371f33c9fd857605c5a30135ff4fd2015cf7fc8675971d448a197c5c6d91857b35ab3601d5c5b3e8722da96c3cc93eaf31f7569e864e9e628421b6338e0491cbe407a3243452ee2007a4fe4c20f6c91c50be875b6178f04605c8fc3b762700d12255c916f35e2e9367fa9798fecf5a88fe3d9c1b0d1154b3779fde45bd44376de95dc5eea787bb868f23c14adf8870035acad57427cf33854b47361d57d5fdcde2b187105373f3b93916efe20fa708af47f74ff04a748575e9594dffc4c8296f6182c27179430faf22286825f378a6fe78d23f2bab6ef1b5e762909bd1dc14bc0f7eaff94d8f9e34a03d6a74782241064b89514fe6a7617a0c4d71d25d906ecf7eec27cfa34728fce19acb70f36210214a54f53c191d0ddc0236586fce596f55b714073af9ffd8e1db90b732c846cbd01867dd0f15652110a336814085a5607e986d489440f7a83e4a9fac17b3918abee978fab3a855ae38e0a7a83ef84e1032191f560f2f6c82f82dad394c54df376bfecfcc8ca65f384742d46756a4d0a25382e33f6c90f50be4fb2e13cbcab91e420ae3c8a6dc2f72fa11f1e8cafce053c7e04ecfb522e5f31de9676b5aaafa2685c2cc4c900a4e43f3d7fd6554f414a594392522cbe7fba08eb640e7331e1c12451437fd0ffe553fe873076428ba59ca433de619e792daa20aa67e9b6c95e4535c8abd1fa3bd2c77255bac6e25250174cc146107e6969425c1472fe43df4f2544984205f2d239f92210bb5f2bf6227571f47b0d4ed375b8586d9bc247dce226d0775423651f0cc5680ea32b94f3cdac65046ff82cc1127be50dafced937f70c4a4ac39fa2636f3b13378fac28398f9f0b44a52683613ed6e5e61fa8c83b0604ac7459d55d67ee5d5983b9cdf068cef996d87546ed39080af3fd2124f7cb702f8a3c405a0a28374dcb0f71a8c2fc5fc6bc9d15e3f8b88c535dc5347831f59b23adf1ea9ca691bc2a554dd27c507db2752601958732b19ac3763a5aac25abcc14278e6a02a5c891f1162db132aeebd49e3ea61ce0405638b8a1e71a968d85ded791480b956e4e0c2729e1bcb1bb4156ea8fc320d94626ce714f575b7e0e34a75ec62074259bc8cb91869b7910407538b2f710fd6c8a1bd8bd114551765384d12e9b8ff06a40c85461a45d5da8ffede03ebbc6a6e37fb258d68bf95c331a2fd86d36b1d3a96c813e0fa2ce29dc4c64b17d4ef1aeb7bd2a73a5405e91bc63585d7fa5597a7e8b297a5f2ba6a2b882f12f5a81f', 1863168);
293
294--index
295create index idx_application_post_id on Application(post_id);
296create index idx_post_specialty_post_id on Post_Specialty(post_id);
297create index idx_post_image_post_id on Post_Image(post_id);
298
299
300
301
302
303
304
305-- View 8
306create or replace view vw_user_notifications as
307select
308 u.user_id,
309 u.first_name,
310 u.last_name,
311 u.username,
312 n.notification_id,
313 n.message,
314 n.is_read,
315 n.created_at as notification_created_at
316from "User" u
317 join notification n on n.user_id = u.user_id
318order by n.created_at desc
319
320-- test
321select *
322from vw_user_notifications
323where user_id = 903515;
324
325insert into notification(message, is_read, created_at, user_id)
326 values ('New worker has sent you an application', false, '2026-03-13 02:20:26.203', 210032)
327
328update notification
329set is_read = true
330where user_id = 210032 and created_at = '2026-03-13 02:20:26.203'
331
332
333
334
335
336
337
338
339-- View 9
340create or replace view vw_worker_applications as
341select
342 w.worker_id,
343 u.first_name,
344 u.last_name,
345 a.application_id,
346 a.message,
347 a.expected_price,
348 a.needed_time,
349 a.created_at,
350 apps.status_name as application_status,
351 p.post_id,
352 p.title as post_title,
353 p.description as post_description,
354 ps.status_name as post_status,
355 l.city,
356 l.region
357from worker w
358 join "User" u on u.user_id = w.user_id
359 join application a on a.worker_id = w.worker_id
360 join application_status apps on apps.status_id = a.status_id
361 join post p on p.post_id = a.post_id
362 join post_status ps on ps.status_id = p.status_id
363 left join location l on l.location_id = p.location_id;
364
365-- test
366select *
367from vw_worker_applications
368where worker_id = 6630371;
369
370