| | 1 | {{{#!sql |
| | 2 | ----------------------------- |
| | 3 | --- WORKER GLOBAL RATINGS --- |
| | 4 | ----------------------------- |
| | 5 | create MATERIALIZED VIEW worker_rating_summary AS |
| | 6 | SELECT |
| | 7 | w.id AS worker_id, |
| | 8 | ua.id AS user_id, |
| | 9 | ROUND(AVG(r.rating), 2) AS avg_rating, |
| | 10 | COUNT(r.id) AS total_reviews |
| | 11 | FROM Worker w |
| | 12 | JOIN UserAccount ua ON ua.id = w.user_id |
| | 13 | LEFT JOIN Review r ON r.reviewed_id = ua.id |
| | 14 | GROUP BY w.id, ua.id; |
| | 15 | |
| | 16 | select * from worker_rating_summary where worker_id = 58064 |
| | 17 | |
| | 18 | ----------------------------- |
| | 19 | -- WORKER CATEGORY RATINGS -- |
| | 20 | ----------------------------- |
| | 21 | CREATE MATERIALIZED VIEW worker_category_rating_summary AS |
| | 22 | SELECT |
| | 23 | w.id AS worker_id, |
| | 24 | tr.category_id, |
| | 25 | ROUND(AVG(r.rating), 2) AS avg_rating, |
| | 26 | COUNT(r.id) AS total_reviews |
| | 27 | FROM Worker w |
| | 28 | JOIN UserAccount ua ON ua.id = w.user_id |
| | 29 | JOIN Offer o ON o.worker_id = w.id |
| | 30 | JOIN Task t ON t.offer_id = o.id |
| | 31 | JOIN TaskRequest tr ON tr.id = o.task_request_id |
| | 32 | JOIN Review r ON r.task_id = t.id |
| | 33 | AND r.reviewed_id = ua.id |
| | 34 | WHERE t.status = 'COMPLETED' |
| | 35 | GROUP BY w.id, tr.category_id; |
| | 36 | |
| | 37 | select * from worker_category_rating_summary where worker_id=95 |
| | 38 | |
| | 39 | |
| | 40 | ----------------------------- |
| | 41 | -- CLIENT GLOBAL RATINGS -- |
| | 42 | ----------------------------- |
| | 43 | CREATE MATERIALIZED VIEW client_rating_summary AS |
| | 44 | SELECT |
| | 45 | c.id AS client_id, |
| | 46 | ua.id AS user_id, |
| | 47 | ROUND(AVG(r.rating), 2) AS avg_rating, |
| | 48 | COUNT(*) AS total_reviews |
| | 49 | FROM Client c |
| | 50 | JOIN UserAccount ua |
| | 51 | ON ua.id = c.user_id |
| | 52 | LEFT JOIN Review r |
| | 53 | ON r.reviewed_id = ua.id |
| | 54 | GROUP BY |
| | 55 | c.id, |
| | 56 | ua.id; |
| | 57 | |
| | 58 | select * from client_rating_summary where client_id=1 |
| | 59 | ----------------------------- |
| | 60 | -- WORKER PROFILE VIEW -- |
| | 61 | ----------------------------- |
| | 62 | create or replace VIEW worker_profile_view AS |
| | 63 | SELECT |
| | 64 | w.id AS worker_id, |
| | 65 | ua.id AS user_id, |
| | 66 | ua.name, |
| | 67 | ua.surname, |
| | 68 | ua.email, |
| | 69 | ua.phone_number, |
| | 70 | w.work_mode, |
| | 71 | w.service_radius_km, |
| | 72 | l.city, |
| | 73 | l.latitude, |
| | 74 | l.longitude, |
| | 75 | wrs.avg_rating, |
| | 76 | wrs.total_reviews |
| | 77 | FROM Worker w |
| | 78 | JOIN UserAccount ua ON ua.id = w.user_id |
| | 79 | JOIN Location l ON l.id = w.location_id |
| | 80 | LEFT JOIN worker_rating_summary wrs |
| | 81 | ON wrs.worker_id = w.id; |
| | 82 | |
| | 83 | select * from worker_profile_view where worker_id = 95 |
| | 84 | |
| | 85 | |
| | 86 | ----------------------------- |
| | 87 | -- Available Task Requests -- |
| | 88 | ----------------------------- |
| | 89 | --(feed/open requests workers can browse) mn e sporo |
| | 90 | --alternativa: parametraized query |
| | 91 | create or replace VIEW available_task_requests_view AS |
| | 92 | SELECT |
| | 93 | tr.id AS task_request_id, |
| | 94 | tr.description, |
| | 95 | tr.work_mode, |
| | 96 | tr.created_at, |
| | 97 | |
| | 98 | c.id AS client_id, |
| | 99 | ua.name AS client_name, |
| | 100 | ua.surname AS client_surname, |
| | 101 | |
| | 102 | cat.id AS category_id, |
| | 103 | cat.category_name, |
| | 104 | |
| | 105 | l.city, |
| | 106 | |
| | 107 | w.id AS worker_id, |
| | 108 | |
| | 109 | ROUND( |
| | 110 | 6371 * ACOS( |
| | 111 | COS(RADIANS(wl.latitude)) * |
| | 112 | COS(RADIANS(l.latitude)) * |
| | 113 | COS(RADIANS(l.longitude) - RADIANS(wl.longitude)) + |
| | 114 | SIN(RADIANS(wl.latitude)) * |
| | 115 | SIN(RADIANS(l.latitude)) |
| | 116 | )::NUMERIC, |
| | 117 | 2) AS distance_km |
| | 118 | |
| | 119 | FROM TaskRequest tr |
| | 120 | JOIN Client c |
| | 121 | ON c.id = tr.client_id |
| | 122 | JOIN UserAccount ua |
| | 123 | ON ua.id = c.user_id |
| | 124 | JOIN Category cat |
| | 125 | ON cat.id = tr.category_id |
| | 126 | JOIN Location l |
| | 127 | ON l.id = tr.location_id |
| | 128 | JOIN WorkerCategory wc |
| | 129 | ON wc.category_id = tr.category_id |
| | 130 | JOIN Worker w |
| | 131 | ON w.id = wc.worker_id |
| | 132 | JOIN Location wl |
| | 133 | ON wl.id = w.location_id |
| | 134 | WHERE tr.status = 'OPEN' |
| | 135 | AND tr.deleted_at IS NULL |
| | 136 | -- cheap prefilter first |
| | 137 | AND ABS(wl.latitude - l.latitude) <= 1 |
| | 138 | AND ABS(wl.longitude - l.longitude) <= 1 |
| | 139 | -- expensive exact filter second |
| | 140 | AND 6371 * ACOS( |
| | 141 | COS(RADIANS(wl.latitude)) * |
| | 142 | COS(RADIANS(l.latitude)) * |
| | 143 | COS(RADIANS(l.longitude) - RADIANS(wl.longitude)) + |
| | 144 | SIN(RADIANS(wl.latitude)) * |
| | 145 | SIN(RADIANS(l.latitude)) |
| | 146 | ) <= w.service_radius_km + 10; |
| | 147 | |
| | 148 | select * from available_task_requests_view where worker_id=95 |
| | 149 | |
| | 150 | |
| | 151 | ----------------------------- |
| | 152 | -- CLIENT PROFILE VIEW -- |
| | 153 | ----------------------------- |
| | 154 | CREATE VIEW client_profile_view AS |
| | 155 | SELECT |
| | 156 | c.id AS client_id, |
| | 157 | ua.id AS user_id, |
| | 158 | ua.name, |
| | 159 | ua.surname, |
| | 160 | ua.email, |
| | 161 | ua.phone_number, |
| | 162 | |
| | 163 | COALESCE(crs.avg_rating, 0) AS avg_rating, |
| | 164 | COALESCE(crs.total_reviews, 0) AS total_reviews |
| | 165 | |
| | 166 | FROM Client c |
| | 167 | |
| | 168 | JOIN UserAccount ua |
| | 169 | ON ua.id = c.user_id |
| | 170 | |
| | 171 | LEFT JOIN client_rating_summary crs |
| | 172 | ON crs.user_id = ua.id; |
| | 173 | |
| | 174 | select * from client_profile_view cpv where client_id=1; |
| | 175 | |
| | 176 | |
| | 177 | ----------------------------- |
| | 178 | -- Matched Workers View -- |
| | 179 | ----------------------------- |
| | 180 | CREATE OR REPLACE VIEW matched_workers_view AS |
| | 181 | SELECT |
| | 182 | w.id AS worker_id, |
| | 183 | |
| | 184 | ua.name, |
| | 185 | ua.surname, |
| | 186 | |
| | 187 | w.work_mode, |
| | 188 | w.service_radius_km, |
| | 189 | |
| | 190 | l.city, |
| | 191 | |
| | 192 | cat.id AS category_id, |
| | 193 | cat.category_name, |
| | 194 | |
| | 195 | wb.badge_id, |
| | 196 | |
| | 197 | b.badge_name, |
| | 198 | b.tier_level, |
| | 199 | b.min_price, |
| | 200 | b.max_price, |
| | 201 | |
| | 202 | COALESCE(wcrs.avg_rating, 0) AS avg_rating, |
| | 203 | |
| | 204 | ROUND( |
| | 205 | 6371 * ACOS( |
| | 206 | COS(RADIANS(trl.latitude)) * |
| | 207 | COS(RADIANS(l.latitude)) * |
| | 208 | COS(RADIANS(l.longitude) - RADIANS(trl.longitude)) + |
| | 209 | SIN(RADIANS(trl.latitude)) * |
| | 210 | SIN(RADIANS(l.latitude)) |
| | 211 | )::NUMERIC, |
| | 212 | 2) AS distance_km, |
| | 213 | |
| | 214 | tr.id AS task_request_id, |
| | 215 | |
| | 216 | c.id AS client_id, |
| | 217 | |
| | 218 | CASE |
| | 219 | WHEN f.id IS NOT NULL THEN TRUE |
| | 220 | ELSE FALSE |
| | 221 | END AS is_favourite |
| | 222 | |
| | 223 | FROM TaskRequest tr |
| | 224 | JOIN Location trl |
| | 225 | ON trl.id = tr.location_id |
| | 226 | JOIN Client c |
| | 227 | ON c.id = tr.client_id |
| | 228 | JOIN WorkerCategory wc |
| | 229 | ON wc.category_id = tr.category_id |
| | 230 | JOIN Worker w |
| | 231 | ON w.id = wc.worker_id |
| | 232 | JOIN UserAccount ua |
| | 233 | ON ua.id = w.user_id |
| | 234 | JOIN Location l |
| | 235 | ON l.id = w.location_id |
| | 236 | JOIN Category cat |
| | 237 | ON cat.id = tr.category_id |
| | 238 | LEFT JOIN worker_category_rating_summary wcrs |
| | 239 | ON wcrs.worker_id = w.id |
| | 240 | AND wcrs.category_id = cat.id |
| | 241 | LEFT JOIN WorkerBadge wb |
| | 242 | ON wb.worker_id = w.id |
| | 243 | AND wb.is_active = TRUE |
| | 244 | LEFT JOIN Badge b |
| | 245 | ON b.id = wb.badge_id |
| | 246 | AND b.category_id = cat.id |
| | 247 | LEFT JOIN Favourite f |
| | 248 | ON f.worker_id = w.id |
| | 249 | AND f.client_id = c.id |
| | 250 | WHERE tr.status = 'OPEN' |
| | 251 | AND tr.deleted_at IS NULL |
| | 252 | -- work mode filter EARLY |
| | 253 | AND ( |
| | 254 | tr.work_mode = 'REMOTE' |
| | 255 | OR w.work_mode = 'REMOTE' |
| | 256 | OR tr.work_mode = w.work_mode |
| | 257 | OR tr.work_mode = 'HYBRID' |
| | 258 | OR w.work_mode = 'HYBRID' |
| | 259 | ) |
| | 260 | -- cheap geo prefilter |
| | 261 | AND ABS(l.latitude - trl.latitude) <= 1 |
| | 262 | AND ABS(l.longitude - trl.longitude) <= 1 |
| | 263 | -- exact distance filter |
| | 264 | AND 6371 * ACOS( |
| | 265 | COS(RADIANS(trl.latitude)) * |
| | 266 | COS(RADIANS(l.latitude)) * |
| | 267 | COS(RADIANS(l.longitude) - RADIANS(trl.longitude)) + |
| | 268 | SIN(RADIANS(trl.latitude)) * |
| | 269 | SIN(RADIANS(l.latitude)) |
| | 270 | ) <= w.service_radius_km; |
| | 271 | |
| | 272 | select * from matched_workers_view where task_request_id = 118 |
| | 273 | |
| | 274 | ----------------------------- |
| | 275 | -- Task Request Offers -- |
| | 276 | ----------------------------- |
| | 277 | CREATE OR REPLACE VIEW task_request_offers_view AS |
| | 278 | |
| | 279 | WITH offer_data AS ( |
| | 280 | SELECT |
| | 281 | o.id AS offer_id, |
| | 282 | |
| | 283 | o.price, |
| | 284 | o.initiated_by, |
| | 285 | o.created_at AS offer_created_at, |
| | 286 | |
| | 287 | tr.id AS task_request_id, |
| | 288 | tr.client_id, |
| | 289 | |
| | 290 | w.id AS worker_id, |
| | 291 | |
| | 292 | ua.name AS worker_name, |
| | 293 | ua.surname AS worker_surname, |
| | 294 | |
| | 295 | w.work_mode, |
| | 296 | |
| | 297 | COALESCE(wrs.avg_rating, 0) AS avg_rating, |
| | 298 | COALESCE(wrs.total_reviews, 0) AS total_reviews, |
| | 299 | |
| | 300 | b.badge_name, |
| | 301 | b.tier_level, |
| | 302 | |
| | 303 | ROUND( |
| | 304 | 6371 * ACOS( |
| | 305 | COS(RADIANS(wl.latitude)) * |
| | 306 | COS(RADIANS(trl.latitude)) * |
| | 307 | COS(RADIANS(trl.longitude) - RADIANS(wl.longitude)) + |
| | 308 | SIN(RADIANS(wl.latitude)) * |
| | 309 | SIN(RADIANS(trl.latitude)) |
| | 310 | )::NUMERIC, |
| | 311 | 2) AS distance_km, |
| | 312 | |
| | 313 | CASE |
| | 314 | WHEN f.id IS NOT NULL THEN TRUE |
| | 315 | ELSE FALSE |
| | 316 | END AS is_favourited |
| | 317 | |
| | 318 | FROM Offer o |
| | 319 | |
| | 320 | JOIN Worker w |
| | 321 | ON w.id = o.worker_id |
| | 322 | |
| | 323 | JOIN UserAccount ua |
| | 324 | ON ua.id = w.user_id |
| | 325 | |
| | 326 | JOIN worker_rating_summary wrs |
| | 327 | ON wrs.worker_id = w.id |
| | 328 | |
| | 329 | JOIN Location wl |
| | 330 | ON wl.id = w.location_id |
| | 331 | |
| | 332 | JOIN TaskRequest tr |
| | 333 | ON tr.id = o.task_request_id |
| | 334 | |
| | 335 | JOIN Location trl |
| | 336 | ON trl.id = tr.location_id |
| | 337 | |
| | 338 | LEFT JOIN WorkerBadge wb |
| | 339 | ON wb.worker_id = w.id |
| | 340 | AND wb.is_active = TRUE |
| | 341 | |
| | 342 | LEFT JOIN Badge b |
| | 343 | ON b.id = wb.badge_id |
| | 344 | AND b.category_id = tr.category_id |
| | 345 | |
| | 346 | LEFT JOIN Favourite f |
| | 347 | ON f.worker_id = w.id |
| | 348 | AND f.client_id = tr.client_id |
| | 349 | |
| | 350 | WHERE o.offer_status = 'PENDING' |
| | 351 | AND o.deleted_at IS NULL |
| | 352 | ) |
| | 353 | |
| | 354 | SELECT |
| | 355 | *, |
| | 356 | |
| | 357 | price = MIN(price) |
| | 358 | OVER (PARTITION BY task_request_id) |
| | 359 | AS is_cheapest, |
| | 360 | |
| | 361 | avg_rating = MAX(avg_rating) |
| | 362 | OVER (PARTITION BY task_request_id) |
| | 363 | AS is_top_rated, |
| | 364 | |
| | 365 | distance_km = MIN(distance_km) |
| | 366 | OVER (PARTITION BY task_request_id) |
| | 367 | AS is_closest |
| | 368 | |
| | 369 | FROM offer_data; |
| | 370 | |
| | 371 | select * from task_request_offers_view where task_request_id = 5000001 |
| | 372 | |
| | 373 | ----------------------------- |
| | 374 | -- Active taks view -- |
| | 375 | ----------------------------- |
| | 376 | CREATE OR REPLACE VIEW active_tasks_view AS |
| | 377 | SELECT t.id AS task_id, |
| | 378 | t.created_at AS task_started_at, |
| | 379 | o.price, |
| | 380 | o.worker_id AS worker_id, |
| | 381 | wu.name AS worker_name, |
| | 382 | wu.surname AS worker_surname, |
| | 383 | tr.client_id, |
| | 384 | cu.name AS client_name, |
| | 385 | cu.surname AS client_surname, |
| | 386 | cat.category_name, |
| | 387 | l.city |
| | 388 | FROM Task t |
| | 389 | JOIN Offer o ON o.id = t.offer_id |
| | 390 | JOIN Worker w ON w.id = o.worker_id |
| | 391 | JOIN UserAccount wu ON wu.id = w.user_id |
| | 392 | JOIN TaskRequest tr ON tr.id = o.task_request_id |
| | 393 | JOIN Client c ON c.id = tr.client_id |
| | 394 | JOIN UserAccount cu ON cu.id = c.user_id |
| | 395 | JOIN Category cat ON cat.id = tr.category_id |
| | 396 | JOIN Location l ON l.id = tr.location_id |
| | 397 | WHERE t.status = 'ACTIVE'; |
| | 398 | |
| | 399 | select * from active_tasks_view where worker_id=95 |
| | 400 | |
| | 401 | ----------------------------- |
| | 402 | -- TASK CHAT -- |
| | 403 | ----------------------------- |
| | 404 | create VIEW task_chat_view AS |
| | 405 | SELECT |
| | 406 | m.id AS message_id, |
| | 407 | m.text, |
| | 408 | m.created_at, |
| | 409 | m.task_id, |
| | 410 | m.sender_id, |
| | 411 | ua.name AS sender_name, |
| | 412 | ua.surname AS sender_surname, |
| | 413 | CASE |
| | 414 | WHEN ua.id = w.user_id THEN 'WORKER' |
| | 415 | WHEN ua.id = c.user_id THEN 'CLIENT' |
| | 416 | END AS sender_role, |
| | 417 | t.status AS task_status, |
| | 418 | o.worker_id, |
| | 419 | tr.client_id |
| | 420 | FROM Message m |
| | 421 | JOIN Task t ON t.id = m.task_id |
| | 422 | AND t.status = 'ACTIVE' |
| | 423 | JOIN Offer o ON o.id = t.offer_id |
| | 424 | JOIN TaskRequest tr ON tr.id = o.task_request_id |
| | 425 | JOIN Worker w ON w.id = o.worker_id |
| | 426 | JOIN Client c ON c.id = tr.client_id |
| | 427 | JOIN UserAccount ua ON ua.id = m.sender_id; |
| | 428 | |
| | 429 | select * from task_chat_view where task_id = 213 |
| | 430 | ----------------------------- |
| | 431 | -- COMPLETED TASKS -- |
| | 432 | ----------------------------- |
| | 433 | CREATE VIEW completed_tasks_view AS |
| | 434 | SELECT |
| | 435 | t.id AS task_id, |
| | 436 | t.created_at AS task_started_at, |
| | 437 | t.updated_at AS task_completed_at, |
| | 438 | o.price, |
| | 439 | o.worker_id, |
| | 440 | wu.name AS worker_name, |
| | 441 | wu.surname AS worker_surname, |
| | 442 | tr.client_id, |
| | 443 | cu.name AS client_name, |
| | 444 | cu.surname AS client_surname, |
| | 445 | tr.category_id, |
| | 446 | cat.category_name, |
| | 447 | l.city |
| | 448 | FROM Task t |
| | 449 | JOIN Offer o ON o.id = t.offer_id |
| | 450 | JOIN TaskRequest tr ON tr.id = o.task_request_id |
| | 451 | JOIN Worker w ON w.id = o.worker_id |
| | 452 | JOIN UserAccount wu ON wu.id = w.user_id |
| | 453 | JOIN Client c ON c.id = tr.client_id |
| | 454 | JOIN UserAccount cu ON cu.id = c.user_id |
| | 455 | JOIN Category cat ON cat.id = tr.category_id |
| | 456 | JOIN Location l ON l.id = tr.location_id |
| | 457 | WHERE t.status = 'COMPLETED'; |
| | 458 | |
| | 459 | select * from completed_tasks_view where worker_id = 95 |
| | 460 | |
| | 461 | ----------------------------- |
| | 462 | -- TASK PAYMENT SUMMARY -- |
| | 463 | ----------------------------- |
| | 464 | -- client payment history, worker earnings history, admin payment monitoring |
| | 465 | CREATE VIEW task_payment_summary_view AS |
| | 466 | SELECT t.id AS task_id, |
| | 467 | p.id AS payment_id, |
| | 468 | p.amount, |
| | 469 | p.payment_method, |
| | 470 | p.status AS payment_status, |
| | 471 | p.created_at AS payment_date, |
| | 472 | c.id AS client_id, |
| | 473 | cu.name AS client_name, |
| | 474 | cu.surname AS client_surname, |
| | 475 | w.id AS worker_id, |
| | 476 | wu.name AS worker_name, |
| | 477 | wu.surname AS worker_surname, |
| | 478 | cat.category_name |
| | 479 | FROM Payment p |
| | 480 | JOIN Task t ON t.id = p.task_id |
| | 481 | JOIN Client c ON c.id = p.client_id |
| | 482 | JOIN UserAccount cu ON cu.id = c.user_id |
| | 483 | JOIN Worker w ON w.id = p.worker_id |
| | 484 | JOIN UserAccount wu ON wu.id = w.user_id |
| | 485 | JOIN Offer o ON o.id = t.offer_id |
| | 486 | JOIN TaskRequest tr ON tr.id = o.task_request_id |
| | 487 | JOIN Category cat ON cat.id = tr.category_id; |
| | 488 | |
| | 489 | select * from task_payment_summary_view where worker_id = 95 |
| | 490 | |
| | 491 | ----------------------------- |
| | 492 | -- OPEN COMPLAINTS VIEW -- |
| | 493 | ----------------------------- |
| | 494 | CREATE VIEW open_complaints_view AS |
| | 495 | SELECT |
| | 496 | comp.id AS complaint_id, |
| | 497 | comp.reason, |
| | 498 | comp.description, |
| | 499 | comp.status, |
| | 500 | comp.created_at, |
| | 501 | comp.task_id, |
| | 502 | cu.name AS client_name, |
| | 503 | cu.surname AS client_surname, |
| | 504 | wu.name AS worker_name, |
| | 505 | wu.surname AS worker_surname, |
| | 506 | cat.category_name |
| | 507 | FROM Complaint comp |
| | 508 | JOIN Client c ON c.id = comp.client_id |
| | 509 | JOIN UserAccount cu ON cu.id = c.user_id |
| | 510 | JOIN Worker w ON w.id = comp.worker_id |
| | 511 | JOIN UserAccount wu ON wu.id = w.user_id |
| | 512 | JOIN Task t ON t.id = comp.task_id |
| | 513 | JOIN Offer o ON o.id = t.offer_id |
| | 514 | JOIN TaskRequest tr ON tr.id = o.task_request_id |
| | 515 | JOIN Category cat ON cat.id = tr.category_id |
| | 516 | WHERE comp.status = 'OPEN'; |
| | 517 | |
| | 518 | select * from open_complaints_view |
| | 519 | }}} |