| 1 | = Analytical and statistical querying = |
| 2 | |
| 3 | == 1. Finding routes and subroutes for arbitrary locations == |
| 4 | This SQL query retrieves trips that include both a specified start location and end location as stops, ensuring the start location comes before the end location in the stop sequence, excluding direct routes between them unless the WHERE clause is commented out. |
| 5 | |
| 6 | {{{ |
| 7 | WITH start_location AS ( |
| 8 | SELECT ts.trip_id, ts.stop_time |
| 9 | FROM trip_stops ts |
| 10 | WHERE ts.location_id = 100 -- ohrid |
| 11 | ), |
| 12 | end_location AS ( |
| 13 | SELECT ts.trip_id, ts.stop_time |
| 14 | FROM trip_stops ts |
| 15 | WHERE ts.location_id = 300 -- skopje |
| 16 | ), |
| 17 | trips AS ( |
| 18 | SELECT s.trip_id |
| 19 | FROM start_location s |
| 20 | JOIN end_location e ON s.trip_id = e.trip_id |
| 21 | WHERE s.stop_time < e.stop_time |
| 22 | ) |
| 23 | SELECT |
| 24 | t.trip_id, |
| 25 | t.route_id, |
| 26 | r.from_location_id, |
| 27 | r.to_location_id, |
| 28 | from_loc.name AS from_name, |
| 29 | to_loc.name AS to_name, |
| 30 | to_org.company_name AS transport_company, |
| 31 | t.status |
| 32 | FROM trip t |
| 33 | JOIN trips tr ON t.trip_id = tr.trip_id |
| 34 | JOIN route r ON t.route_id = r.route_id |
| 35 | JOIN location from_loc ON r.from_location_id = from_loc.location_id |
| 36 | JOIN location to_loc ON r.to_location_id = to_loc.location_id |
| 37 | JOIN transport_organizer to_org ON r.transport_organizer_id = to_org.transport_organizer_id |
| 38 | WHERE NOT (r.from_location_id = 100 AND r.to_location_id = 300) -- commenting this line here gives ONLY SUBROUTES! |
| 39 | }}} |
| 40 | |
| 41 | == 2. Transport company performance overview == |
| 42 | This SQL query aggregates performance metrics for each transport organizer, including routes operated, trips organized, tickets sold, total revenue, average ticket price, unique customers, and average rating, sorted by total revenue in descending order. |
| 43 | |
| 44 | {{{ |
| 45 | WITH company_performance AS ( |
| 46 | SELECT |
| 47 | to_org.company_name, |
| 48 | COUNT(DISTINCT r.route_id) as routes_operated, |
| 49 | COUNT(DISTINCT t.trip_id) as trips_organized, |
| 50 | COUNT(tk.ticket_id) as total_tickets_sold, |
| 51 | SUM(COALESCE(tk.price, 0)) as total_revenue, |
| 52 | AVG(COALESCE(tk.price, 0)) as avg_ticket_price, |
| 53 | COUNT(DISTINCT tk.account_id) as unique_customers, |
| 54 | AVG(COALESCE(rev.rating, 0)) as avg_rating |
| 55 | FROM transport_organizer to_org |
| 56 | JOIN route r ON to_org.transport_organizer_id = r.transport_organizer_id |
| 57 | JOIN trip t ON r.route_id = t.route_id |
| 58 | LEFT JOIN ticket tk ON t.trip_id = tk.trip_id |
| 59 | LEFT JOIN review rev ON tk.ticket_id = rev.ticket_id |
| 60 | GROUP BY to_org.transport_organizer_id, to_org.company_name |
| 61 | ) |
| 62 | SELECT |
| 63 | company_name, |
| 64 | routes_operated, |
| 65 | trips_organized, |
| 66 | total_tickets_sold, |
| 67 | total_revenue, |
| 68 | avg_ticket_price, |
| 69 | unique_customers, |
| 70 | ROUND(avg_rating, 2) as avg_rating |
| 71 | FROM company_performance |
| 72 | ORDER BY total_revenue DESC; |
| 73 | |
| 74 | }}} |
| 75 | |
| 76 | == 3. Top user-purchased routes == |
| 77 | This SQL query retrieves the top three routes most frequently purchased by a specified user, based on ticket counts, including route details and transport company, sorted by tickets purchased in descending order. Useful for fast recommendation of routes per user. |
| 78 | |
| 79 | {{{ |
| 80 | SELECT |
| 81 | r.route_id, |
| 82 | l_from.name AS from_location, |
| 83 | l_to.name AS to_location, |
| 84 | COUNT(t.ticket_id) AS tickets_purchased, |
| 85 | to_.company_name AS transport_company |
| 86 | FROM ticket t |
| 87 | JOIN trip tr ON t.trip_id = tr.trip_id |
| 88 | JOIN route r ON tr.route_id = r.route_id |
| 89 | JOIN location l_from ON r.from_location_id = l_from.location_id |
| 90 | JOIN location l_to ON r.to_location_id = l_to.location_id |
| 91 | JOIN transport_organizer to_ ON r.transport_organizer_id = to_.transport_organizer_id |
| 92 | WHERE t.account_id = 300 -- this can be changed arbitrarily |
| 93 | GROUP BY r.route_id, l_from.name, l_to.name, to_.company_name |
| 94 | ORDER BY tickets_purchased DESC |
| 95 | LIMIT 3; |
| 96 | }}} |
| 97 | |
| 98 | == 4. Ticket sales revenue by weekday and route == |
| 99 | |
| 100 | This query analyzes completed trips to show ticket volume, total and average revenue, and route details. Useful to check trends throughout the week. |
| 101 | |
| 102 | {{{ |
| 103 | SELECT |
| 104 | TO_CHAR(tk.date_purchased, 'Day') AS day_of_week, |
| 105 | COUNT(tk.ticket_id) AS total_tickets, |
| 106 | SUM(p.total_price) AS total_revenue, |
| 107 | AVG(p.total_price) AS avg_ticket_price, |
| 108 | r.from_location_id, |
| 109 | r.to_location_id |
| 110 | FROM ticket tk |
| 111 | JOIN payment p ON tk.payment_id = p.payment_id |
| 112 | JOIN trip t ON tk.trip_id = t.trip_id |
| 113 | JOIN route r ON t.route_id = r.route_id |
| 114 | WHERE t.status = 'COMPLETED' |
| 115 | GROUP BY TO_CHAR(tk.date_purchased, 'Day'), r.from_location_id, r.to_location_id |
| 116 | ORDER BY total_tickets DESC; |
| 117 | }}} |