|
| 1 | +--- |
| 2 | +comments: true |
| 3 | +difficulty: Medium |
| 4 | +edit_url: https://github.com/doocs/leetcode/edit/main/solution/3300-3399/3308.Find%20Top%20Performing%20Driver/README_EN.md |
| 5 | +tags: |
| 6 | + - Database |
| 7 | +--- |
| 8 | + |
| 9 | +<!-- problem:start --> |
| 10 | + |
| 11 | +# [3308. Find Top Performing Driver 🔒](https://leetcode.com/problems/find-top-performing-driver) |
| 12 | + |
| 13 | +[中文文档](/solution/3300-3399/3308.Find%20Top%20Performing%20Driver/README.md) |
| 14 | + |
| 15 | +## Description |
| 16 | + |
| 17 | +<!-- description:start --> |
| 18 | + |
| 19 | +<p>Table: <font face="monospace"><code>Drivers</code></font></p> |
| 20 | + |
| 21 | +<pre> |
| 22 | ++--------------+---------+ |
| 23 | +| Column Name | Type | |
| 24 | ++--------------+---------+ |
| 25 | +| driver_id | int | |
| 26 | +| name | varchar | |
| 27 | +| age | int | |
| 28 | +| experience | int | |
| 29 | +| accidents | int | |
| 30 | ++--------------+---------+ |
| 31 | +(driver_id) is the unique key for this table. |
| 32 | +Each row includes a driver's ID, their name, age, years of driving experience, and the number of accidents they’ve had. |
| 33 | +</pre> |
| 34 | + |
| 35 | +<p>Table: <font face="monospace"><code>Vehicles</code></font></p> |
| 36 | + |
| 37 | +<pre> |
| 38 | ++--------------+---------+ |
| 39 | +| vehicle_id | int | |
| 40 | +| driver_id | int | |
| 41 | +| model | varchar | |
| 42 | +| fuel_type | varchar | |
| 43 | +| mileage | int | |
| 44 | ++--------------+---------+ |
| 45 | +(vehicle_id, driver_id, fuel_type) is the unique key for this table. |
| 46 | +Each row includes the vehicle's ID, the driver who operates it, the model, fuel type, and mileage. |
| 47 | +</pre> |
| 48 | + |
| 49 | +<p>Table: <font face="monospace"><code>Trips</code></font></p> |
| 50 | + |
| 51 | +<pre> |
| 52 | ++--------------+---------+ |
| 53 | +| trip_id | int | |
| 54 | +| vehicle_id | int | |
| 55 | +| distance | int | |
| 56 | +| duration | int | |
| 57 | +| rating | int | |
| 58 | ++--------------+---------+ |
| 59 | +(trip_id) is the unique key for this table. |
| 60 | +Each row includes a trip's ID, the vehicle used, the distance covered (in miles), the trip duration (in minutes), and the passenger's rating (1-5). |
| 61 | +</pre> |
| 62 | + |
| 63 | +<p>Uber is analyzing drivers based on their trips. Write a solution to find the <strong>top-performing driver</strong> for <strong>each fuel type</strong> based on the following criteria:</p> |
| 64 | + |
| 65 | +<ol> |
| 66 | + <li>A driver's performance is calculated as the <strong>average rating</strong> across all their trips. Average rating should be rounded to <code>2</code> decimal places.</li> |
| 67 | + <li>If two drivers have the same average rating, the driver with the <strong>longer total distance</strong> traveled should be ranked higher.</li> |
| 68 | + <li>If there is <strong>still a tie</strong>, choose the driver with the <strong>fewest accidents</strong>.</li> |
| 69 | +</ol> |
| 70 | + |
| 71 | +<p>Return <em>the result table ordered by</em> <code>fuel_type</code> <em>in </em><strong>ascending</strong><em> order.</em></p> |
| 72 | + |
| 73 | +<p>The result format is in the following example.</p> |
| 74 | + |
| 75 | +<p> </p> |
| 76 | +<p><strong class="example">Example:</strong></p> |
| 77 | + |
| 78 | +<div class="example-block"> |
| 79 | +<p><strong>Input:</strong></p> |
| 80 | + |
| 81 | +<p><code>Drivers</code> table:</p> |
| 82 | + |
| 83 | +<pre class="example-io"> |
| 84 | ++-----------+----------+-----+------------+-----------+ |
| 85 | +| driver_id | name | age | experience | accidents | |
| 86 | ++-----------+----------+-----+------------+-----------+ |
| 87 | +| 1 | Alice | 34 | 10 | 1 | |
| 88 | +| 2 | Bob | 45 | 20 | 3 | |
| 89 | +| 3 | Charlie | 28 | 5 | 0 | |
| 90 | ++-----------+----------+-----+------------+-----------+ |
| 91 | +</pre> |
| 92 | + |
| 93 | +<p><code>Vehicles</code> table:</p> |
| 94 | + |
| 95 | +<pre class="example-io"> |
| 96 | ++------------+-----------+---------+-----------+---------+ |
| 97 | +| vehicle_id | driver_id | model | fuel_type | mileage | |
| 98 | ++------------+-----------+---------+-----------+---------+ |
| 99 | +| 100 | 1 | Sedan | Gasoline | 20000 | |
| 100 | +| 101 | 2 | SUV | Electric | 30000 | |
| 101 | +| 102 | 3 | Coupe | Gasoline | 15000 | |
| 102 | ++------------+-----------+---------+-----------+---------+ |
| 103 | +</pre> |
| 104 | + |
| 105 | +<p><code>Trips</code> table:</p> |
| 106 | + |
| 107 | +<pre class="example-io"> |
| 108 | ++---------+------------+----------+----------+--------+ |
| 109 | +| trip_id | vehicle_id | distance | duration | rating | |
| 110 | ++---------+------------+----------+----------+--------+ |
| 111 | +| 201 | 100 | 50 | 30 | 5 | |
| 112 | +| 202 | 100 | 30 | 20 | 4 | |
| 113 | +| 203 | 101 | 100 | 60 | 4 | |
| 114 | +| 204 | 101 | 80 | 50 | 5 | |
| 115 | +| 205 | 102 | 40 | 30 | 5 | |
| 116 | +| 206 | 102 | 60 | 40 | 5 | |
| 117 | ++---------+------------+----------+----------+--------+ |
| 118 | +</pre> |
| 119 | + |
| 120 | +<p><strong>Output:</strong></p> |
| 121 | + |
| 122 | +<pre class="example-io"> |
| 123 | ++-----------+-----------+--------+----------+ |
| 124 | +| fuel_type | driver_id | rating | distance | |
| 125 | ++-----------+-----------+--------+----------+ |
| 126 | +| Electric | 2 | 4.50 | 180 | |
| 127 | +| Gasoline | 3 | 5.00 | 100 | |
| 128 | ++-----------+-----------+--------+----------+ |
| 129 | +</pre> |
| 130 | + |
| 131 | +<p><strong>Explanation:</strong></p> |
| 132 | + |
| 133 | +<ul> |
| 134 | + <li>For fuel type <code>Gasoline</code>, both Alice (Driver 1) and Charlie (Driver 3) have trips. Charlie has an average rating of 5.0, while Alice has 4.5. Therefore, Charlie is selected.</li> |
| 135 | + <li>For fuel type <code>Electric</code>, Bob (Driver 2) is the only driver with an average rating of 4.5, so he is selected.</li> |
| 136 | +</ul> |
| 137 | + |
| 138 | +<p>The output table is ordered by <code>fuel_type</code> in ascending order.</p> |
| 139 | +</div> |
| 140 | + |
| 141 | +<!-- description:end --> |
| 142 | + |
| 143 | +## Solutions |
| 144 | + |
| 145 | +<!-- solution:start --> |
| 146 | + |
| 147 | +### Solution 1: Equi-join + Grouping + Window Function |
| 148 | + |
| 149 | +We can use equi-join to join the `Drivers` table with the `Vehicles` table on `driver_id`, and then join with the `Trips` table on `vehicle_id`. Next, we group by `fuel_type` and `driver_id` to calculate each driver's average rating, total mileage, and total accident count. Then, using the `RANK()` window function, we rank the drivers of each fuel type in descending order of rating, descending order of total mileage, and ascending order of total accident count. Finally, we filter out the driver ranked 1 for each fuel type. |
| 150 | + |
| 151 | +<!-- tabs:start --> |
| 152 | + |
| 153 | +#### MySQL |
| 154 | + |
| 155 | +```sql |
| 156 | +# Write your MySQL query statement below |
| 157 | +WITH |
| 158 | + T AS ( |
| 159 | + SELECT |
| 160 | + fuel_type, |
| 161 | + driver_id, |
| 162 | + ROUND(AVG(rating), 2) rating, |
| 163 | + SUM(distance) distance, |
| 164 | + SUM(accidents) accidents |
| 165 | + FROM |
| 166 | + Drivers |
| 167 | + JOIN Vehicles USING (driver_id) |
| 168 | + JOIN Trips USING (vehicle_id) |
| 169 | + GROUP BY fuel_type, driver_id |
| 170 | + ), |
| 171 | + P AS ( |
| 172 | + SELECT |
| 173 | + *, |
| 174 | + RANK() OVER ( |
| 175 | + PARTITION BY fuel_type |
| 176 | + ORDER BY rating DESC, distance DESC, accidents |
| 177 | + ) rk |
| 178 | + FROM T |
| 179 | + ) |
| 180 | +SELECT fuel_type, driver_id, rating, distance |
| 181 | +FROM P |
| 182 | +WHERE rk = 1 |
| 183 | +ORDER BY 1; |
| 184 | +``` |
| 185 | + |
| 186 | +<!-- tabs:end --> |
| 187 | + |
| 188 | +<!-- solution:end --> |
| 189 | + |
| 190 | +<!-- problem:end --> |
0 commit comments