Description
Table: Trips
| Column Name | Type |
|---|---|
| id | int |
| client_id | int |
| driver_id | int |
| city_id | int |
| status | enum |
| request_at | date |
idis the primary key (column with unique values) for this table.- The table holds all taxi trips. Each trip has a unique
id, whileclient_idanddriver_idare foreign keys to theusers_idat theUserstable. Statusis an ENUM (category) type of (‘completed’, ‘cancelled_by_driver’, ‘cancelled_by_client’).
Table: Users
| Column Name | Type |
|---|---|
| users_id | int |
| banned | enum |
| role | enum |
users_idis the primary key (column with unique values) for this table.The table holds all users. Each user has a unique
users_id, androleis an ENUM type of (‘client’, ‘driver’, ‘partner’).bannedis an ENUM (category) type of (‘Yes’, ‘No’).The cancellation rate is computed by dividing the number of canceled (by client or driver) requests with unbanned users by the total number of requests with unbanned users on that day.
Problem Statement
Write a solution to find the cancellation rate of requests with unbanned users (both client and driver must not be banned) each day between “2013-10-01” and “2013-10-03”. Round Cancellation Rate to two decimal points.
Return the result table in any order. The result format is in the following example.
Example 1:
Input:
Trips table:
| id | client_id | driver_id | city_id | status | request_at |
|---|---|---|---|---|---|
| 1 | 1 | 10 | 1 | completed | 2013-10-01 |
| 2 | 2 | 11 | 1 | cancelled_by_driver | 2013-10-01 |
| 3 | 3 | 12 | 6 | completed | 2013-10-01 |
| 4 | 4 | 13 | 6 | cancelled_by_client | 2013-10-01 |
| 5 | 1 | 10 | 1 | completed | 2013-10-02 |
| 6 | 2 | 11 | 6 | completed | 2013-10-02 |
| 7 | 3 | 12 | 6 | completed | 2013-10-02 |
| 8 | 2 | 12 | 12 | completed | 2013-10-03 |
| 9 | 3 | 10 | 12 | completed | 2013-10-03 |
| 10 | 4 | 13 | 12 | cancelled_by_driver | 2013-10-03 |
Users table:
| users_id | banned | role |
|---|---|---|
| 1 | No | client |
| 2 | Yes | client |
| 3 | No | client |
| 4 | No | client |
| 10 | No | driver |
| 11 | No | driver |
| 12 | No | driver |
| 13 | No | driver |
Output:
| Day | Cancellation Rate |
|---|---|
| 2013-10-01 | 0.33 |
| 2013-10-02 | 0.00 |
| 2013-10-03 | 0.50 |
Explanation:
On 2013-10-01:
- There were 4 requests in total, 2 of which were canceled.
- However, the request with
id=2was made by a banned client (User_Id=2), so it is ignored in the calculation. - Hence there are 3 unbanned requests in total, 1 of which was canceled.
- The Cancellation Rate is
(1 / 3) = 0.33
On 2013-10-02:
- There were 3 requests in total, 0 of which were canceled.
- The request with
Id=6was made by a banned client, so it is ignored. - Hence there are 2 unbanned requests in total, 0 of which were canceled.
- The Cancellation Rate is
(0 / 2) = 0.00
On 2013-10-03:
- There were 3 requests in total, 1 of which was canceled.
- The request with
Id=8was made by a banned client, so it is ignored. - Hence there are 2 unbanned request in total, 1 of which were canceled.
- The Cancellation Rate is
(1 / 2) = 0.50
Solution
The problem can be divided into following parts.
- We need to find unbanned users. This information is stored in the
Userstable. - You need to find cancelled trips between “2013-10-01” and “2013-10-03”, but you need only those cancelled trips which are not by the banned users. This means you need information from both tables. Hence a join is required.
- You need to find cancelled requests per day and you need to find total requests per day ignoring banned users’ requests. This means you need aggregation on a per day basis.
- Next, you need to find the cancellation rate which is number of cancelled requests per day divided by total requests per day and you need to round this number by two decimal places.
1. Finding unbanned users
You can find unbanned users using the WHERE clause. Alternatively, you could use banned = 'No' condition.
1SELECT users_id FROM Users WHERE banned != 'Yes';
2. Find cancelled trips by unbanned users
In order to find cancelled trips you can use Trips table, but you need to find trips cancelled by unbanned users. This is where you need to join with Users table and filter by banned != 'Yes' condition. You need to verify that neither the client nor the driver is banned. For this, you need to join with Users table again. Below query gives all trips which are cancelled by unbanned users.
1SELECT * FROM Trips t
2 JOIN Users u
3 ON t.client_id = u.users_id AND u.banned != 'Yes'
4 JOIN Users u
5 ON t.driver_id = u.users_id AND u.banned != 'Yes'
6 WHERE t.request_at BETWEEN '2013-10-01' AND '2013-10-03' ;
3. Find cancelled trips per day
This is essentially asking to use GROUP BY clause on the column request_at to find the number of cancelled requests per day. Once it has been grouped, you can calculate the total number of requests per day. In order to get cancelled requests count, you might need to check using status column.
1SELECT
2 request_at,
3 SUM(CASE WHEN status = 'cancelled_by_driver' OR status = 'cancelled_by_client' THEN 1 ELSE 0 END) AS cancelled_requests,
4 COUNT(1) AS total_cancelled
5 FROM Trips t
6 ON t.client_id = u.users_id AND u.banned != 'Yes'
7 JOIN Users u
8 ON t.driver_id = u.users_id AND u.banned != 'Yes'
9 WHERE t.request_at BETWEEN '2013-10-01' AND '2013-10-03'
10 GROUP BY request_at;
4. Find Cancellation Rate
This can be done by dividing cancelled_requests by total_cancelled and rounding it to two decimal places. You can perform this in the same query or you can use CTE for this.
1SELECT ROUND(SUM(CASE WHEN status = 'cancelled_by_driver' OR status = 'cancelled_by_client' THEN 1 ELSE 0 END) /
2 COUNT(1)) AS cancellation_rate;
Hence, the complete solution for this problem looks like below.
1SELECT
2 request_at Day,
3 ROUND(SUM(CASE WHEN status = 'cancelled_by_driver' OR status = 'cancelled_by_client' THEN 1 ELSE 0 END) /
4 COUNT(1), 2) AS 'Cancellation Rate'
5 FROM Trips t
6 JOIN Users u
7 ON t.client_id = u.users_id AND u.banned != 'Yes'
8 JOIN Users d
9 ON t.driver_id = d.users_id AND d.banned != 'Yes'
10 WHERE t.request_at BETWEEN '2013-10-01' AND '2013-10-03'
11 GROUP BY request_at
12 ORDER BY request_at;


Comments