| | 1 | = Advanced Reports |
| | 2 | == Finding the most active users on the app during a given time period |
| | 3 | This SQL query wants to find the most active users. Active are users who create listings, write reviews, handle appointments and save favorites. |
| | 4 | This query: |
| | 5 | * Counts each type of activity |
| | 6 | * Combines everything per user |
| | 7 | * Calculates the final score |
| | 8 | * Ranks the users from most to least active |
| | 9 | === SQL |
| | 10 | {{{ |
| | 11 | WITH |
| | 12 | params AS ( |
| | 13 | SELECT |
| | 14 | CAST(:start_ts AS timestamp) AS start_ts, |
| | 15 | CAST(:end_ts AS timestamp) AS end_ts |
| | 16 | ), |
| | 17 | |
| | 18 | listings_by_user AS ( |
| | 19 | SELECT |
| | 20 | l.owner_id AS user_id, |
| | 21 | COUNT(*) AS listings_created |
| | 22 | FROM listings l |
| | 23 | JOIN params p ON l.created_at >= p.start_ts AND l.created_at < p.end_ts |
| | 24 | GROUP BY l.owner_id |
| | 25 | ), |
| | 26 | |
| | 27 | reviews_by_user AS ( |
| | 28 | SELECT |
| | 29 | r.reviewer_id AS user_id, |
| | 30 | COUNT(*) AS reviews_left, |
| | 31 | AVG(r.rating)::numeric(10,2) AS avg_rating_left |
| | 32 | FROM reviews r |
| | 33 | JOIN params p ON r.created_at >= p.start_ts AND r.created_at < p.end_ts |
| | 34 | GROUP BY r.reviewer_id |
| | 35 | ), |
| | 36 | |
| | 37 | appointments_by_user AS ( |
| | 38 | SELECT |
| | 39 | a.responsible_owner_id AS user_id, |
| | 40 | COUNT(*) AS appointments_total, |
| | 41 | COUNT(*) FILTER (WHERE a.status = 'DONE') AS appointments_done, |
| | 42 | COUNT(*) FILTER (WHERE a.status = 'NO_SHOW') AS appointments_no_show, |
| | 43 | COUNT(*) FILTER (WHERE a.status = 'CANCELLED')AS appointments_cancelled |
| | 44 | FROM appointments a |
| | 45 | JOIN params p ON a.date_time >= p.start_ts AND a.date_time < p.end_ts |
| | 46 | GROUP BY a.responsible_owner_id |
| | 47 | ), |
| | 48 | |
| | 49 | favorites_by_user AS ( |
| | 50 | SELECT |
| | 51 | f.client_id AS user_id, |
| | 52 | COUNT(*) AS favorites_saved_all_time |
| | 53 | FROM favorite_listings f |
| | 54 | GROUP BY f.client_id |
| | 55 | ) |
| | 56 | |
| | 57 | SELECT |
| | 58 | u.user_id, |
| | 59 | u.username, |
| | 60 | u.email, |
| | 61 | u.name, |
| | 62 | u.surname, |
| | 63 | |
| | 64 | COALESCE(l.listings_created, 0) AS listings_created, |
| | 65 | COALESCE(rv.reviews_left, 0) AS reviews_left, |
| | 66 | COALESCE(rv.avg_rating_left, 0) AS avg_rating_left, |
| | 67 | COALESCE(ap.appointments_total, 0) AS appointments_total, |
| | 68 | COALESCE(ap.appointments_done, 0) AS appointments_done, |
| | 69 | COALESCE(ap.appointments_no_show, 0) AS appointments_no_show, |
| | 70 | COALESCE(ap.appointments_cancelled, 0) AS appointments_cancelled, |
| | 71 | COALESCE(fv.favorites_saved_all_time, 0) AS favorites_saved_all_time, |
| | 72 | |
| | 73 | ( |
| | 74 | COALESCE(l.listings_created, 0) * 5 |
| | 75 | + COALESCE(rv.reviews_left, 0) * 3 |
| | 76 | + COALESCE(ap.appointments_done, 0) * 2 |
| | 77 | + COALESCE(fv.favorites_saved_all_time, 0) * 1 |
| | 78 | - COALESCE(ap.appointments_no_show, 0) * 2 |
| | 79 | ) AS activity_score, |
| | 80 | |
| | 81 | DENSE_RANK() OVER ( |
| | 82 | ORDER BY |
| | 83 | ( |
| | 84 | COALESCE(l.listings_created, 0) * 5 |
| | 85 | + COALESCE(rv.reviews_left, 0) * 3 |
| | 86 | + COALESCE(ap.appointments_done, 0) * 2 |
| | 87 | + COALESCE(fv.favorites_saved_all_time, 0) * 1 |
| | 88 | - COALESCE(ap.appointments_no_show, 0) * 2 |
| | 89 | ) DESC, |
| | 90 | COALESCE(l.listings_created, 0) DESC, |
| | 91 | COALESCE(rv.reviews_left, 0) DESC |
| | 92 | ) AS activity_rank |
| | 93 | |
| | 94 | FROM users u |
| | 95 | LEFT JOIN listings_by_user l ON l.user_id = u.user_id |
| | 96 | LEFT JOIN reviews_by_user rv ON rv.user_id = u.user_id |
| | 97 | LEFT JOIN appointments_by_user ap ON ap.user_id = u.user_id |
| | 98 | LEFT JOIN favorites_by_user fv ON fv.user_id = u.user_id |
| | 99 | |
| | 100 | WHERE |
| | 101 | COALESCE(l.listings_created, 0) |
| | 102 | + COALESCE(rv.reviews_left, 0) |
| | 103 | + COALESCE(ap.appointments_total, 0) |
| | 104 | + COALESCE(fv.favorites_saved_all_time, 0) > 0 |
| | 105 | |
| | 106 | ORDER BY activity_rank |
| | 107 | LIMIT :top_n; |
| | 108 | |
| | 109 | }}} |
| | 110 | === Relation |
| | 111 | {{{ |
| | 112 | Relation |
| | 113 | }}} |