Description

Table: Trips

Column NameType
idint
client_idint
driver_idint
city_idint
statusenum
request_atdate
  • id is the primary key (column with unique values) for this table.
  • The table holds all taxi trips. Each trip has a unique id, while client_id and driver_id are foreign keys to the users_id at the Users table.
  • Status is an ENUM (category) type of (‘completed’, ‘cancelled_by_driver’, ‘cancelled_by_client’).

Table: Users

Column NameType
users_idint
bannedenum
roleenum
  • users_id is the primary key (column with unique values) for this table.

  • The table holds all users. Each user has a unique users_id, and role is an ENUM type of (‘client’, ‘driver’, ‘partner’).

  • banned is 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:

idclient_iddriver_idcity_idstatusrequest_at
11101completed2013-10-01
22111cancelled_by_driver2013-10-01
33126completed2013-10-01
44136cancelled_by_client2013-10-01
51101completed2013-10-02
62116completed2013-10-02
73126completed2013-10-02
821212completed2013-10-03
931012completed2013-10-03
1041312cancelled_by_driver2013-10-03

Users table:

users_idbannedrole
1Noclient
2Yesclient
3Noclient
4Noclient
10Nodriver
11Nodriver
12Nodriver
13Nodriver

Output:

DayCancellation Rate
2013-10-010.33
2013-10-020.00
2013-10-030.50

Explanation:

On 2013-10-01:

  • There were 4 requests in total, 2 of which were canceled.
  • However, the request with id=2 was 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=6 was 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=8 was 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.

  1. We need to find unbanned users. This information is stored in the Users table.
  2. 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.
  3. 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.
  4. 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;