1. 程式人生 > >Leetcode之mysql專題《Trips and Users》

Leetcode之mysql專題《Trips and Users》

The Trips table holds all taxi trips. Each trip has a unique Id, while Client_Id and Driver_Id are both foreign keys to the Users_Id at the Users table. Status is an ENUM type of (‘completed’, ‘cancelled_by_driver’, ‘cancelled_by_client’).

+----+-----------+-----------+---------+--------------------+----------+
| 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|
+----+-----------+-----------+---------+--------------------+----------+

The Users table holds all users. Each user has an unique Users_Id, and Role is an ENUM type of (‘client’, ‘driver’, ‘partner’).

+----------+--------+--------+
| 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 |
+----------+--------+--------+

Write a SQL query to find the cancellation rate of requests made by unbanned users between Oct 1, 2013 and Oct 3, 2013. For the above tables, your SQL query should return the following rows with the cancellation rate being rounded to two decimal places.

+------------+-------------------+
|     Day    | Cancellation Rate |
+------------+-------------------+
| 2013-10-01 |       0.33        |
| 2013-10-02 |       0.00        |
| 2013-10-03 |       0.50        |
+------------+-------------------+

題解思路如下:

1. 看到這道題,應該先把Trips表記錄中Client_ID和Driver_ID中對應在Users表的Banned欄位為No的記錄過濾掉,

即Trips表記錄中有效記錄內容為

Trips t 

JOIN Users uc ON t.Client_ID = uc.Users_ID AND uc.Banned = "No" 

JOIN Users ud ON t.Driver_ID = ud.Users_ID AND ud.Banned = "No"

2. 接著,把Trips表記錄中Request_at處於Oct 1, 2013 and Oct 3, 2013的記錄篩選出來

WHERE Request_at BETWEEN "2013-10-01" AND "2013-10-03"

3. 再接著,因為結果要求按Request_at分組統計,所以要加上

  GROUP BY Request_at

4. 最後的難點在於計算cancellation rate,其實cancellation rate就是拿每天未完成訂單數除以當天總訂單數,其中當天總訂單數可以用count(*)表示,每天未完成訂單數就是Status不是completed的個數,即SUM(t.Status != 'completed'),保留2位小數點可以用ROUND(輸入值,2)表示,於是得到select的物件為

SELECT Request_at as 'Day', ROUND( SUM(t.Status != 'completed') / COUNT(*), 2) as 'Cancellation Rate'

5. 彙總一下即可得到問題的答案如下

SELECT Request_at as 'Day', ROUND( SUM(t.Status != 'completed') / COUNT(*), 2) as 'Cancellation Rate'     FROM Trips t      JOIN Users uc ON t.Client_ID = uc.Users_ID AND uc.Banned = "No"     JOIN Users ud ON t.Driver_ID = ud.Users_ID AND ud.Banned = "No"     WHERE Request_at BETWEEN "2013-10-01" AND "2013-10-03"     GROUP BY Request_at;