LeetCode:Trips and Users - 出租車接單取消率

一、題目名稱sql

Trips and Users(出租車預定取消率)數據庫

二、題目地址命令行

https://leetcode.com/problems/trips-and-users/code

三、題目內容ip

表Trips內存儲了出租車的接單數據,包括Id、Client_Id、Driver_Id、City_Id、Status、Request_at共計6列,其中Status列是個枚舉列,包括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|
+----+-----------+-----------+---------+--------------------+----------+

 

表Users存儲了全部的用戶數據信息,每一個用戶有一個惟一的Users_Id,Role是一個枚舉列,包括client(客戶)、driver(司機)、partner(合做夥伴)三項:leetcode

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

 

寫一個SQL語句,查詢非禁止客戶(Users表中Banned列爲No的客戶)在2013年10月1日至2013年10月3日間的單據取消率,結果爲四捨五入後的兩位有效數字。get

四、初始化數據庫腳本it

在MySQL數據庫中創建一個名爲LEETCODE的數據庫,用MySQL命令行中的source命令執行下面腳本:io

-- 執行腳本前必須創建名爲LEETCODE的DATABASE
USE LEETCODE;
 
DROP TABLE IF EXISTS Trips;
CREATE TABLE Trips (
  Id INT NOT NULL PRIMARY KEY,
  Client_Id INT,
  Driver_Id INT,
  City_Id INT,
  Status ENUM('completed', 'cancelled_by_driver', 'cancelled_by_client'),
  Request_at DATE
);

INSERT INTO Trips (Id, Client_Id, Driver_Id, City_Id, Status, Request_at) 
  VALUES (1, 1, 10, 1, 'completed', '2013-10-01');
INSERT INTO Trips (Id, Client_Id, Driver_Id, City_Id, Status, Request_at) 
  VALUES (2, 2, 11, 1, 'cancelled_by_driver', '2013-10-01');
INSERT INTO Trips (Id, Client_Id, Driver_Id, City_Id, Status, Request_at) 
  VALUES (3, 3, 12, 6, 'completed', '2013-10-01');
INSERT INTO Trips (Id, Client_Id, Driver_Id, City_Id, Status, Request_at) 
  VALUES (4, 4, 13, 6, 'cancelled_by_client', '2013-10-01');
INSERT INTO Trips (Id, Client_Id, Driver_Id, City_Id, Status, Request_at) 
  VALUES (5, 1, 10, 1, 'completed', '2013-10-02');
INSERT INTO Trips (Id, Client_Id, Driver_Id, City_Id, Status, Request_at) 
  VALUES (6, 2, 11, 6, 'completed', '2013-10-02');
INSERT INTO Trips (Id, Client_Id, Driver_Id, City_Id, Status, Request_at) 
  VALUES (7, 3, 12, 6, 'completed', '2013-10-02');
INSERT INTO Trips (Id, Client_Id, Driver_Id, City_Id, Status, Request_at) 
  VALUES (8, 2, 12, 12, 'completed', '2013-10-03');
INSERT INTO Trips (Id, Client_Id, Driver_Id, City_Id, Status, Request_at) 
  VALUES (9, 3, 10, 12, 'completed', '2013-10-03');
INSERT INTO Trips (Id, Client_Id, Driver_Id, City_Id, Status, Request_at) 
  VALUES (10, 4, 13, 12, 'cancelled_by_driver', '2013-10-03');

DROP TABLE IF EXISTS Users;
CREATE TABLE Users (
  Users_Id INT NOT NULL PRIMARY KEY,
  Banned VARCHAR(5),
  Role ENUM('client', 'driver', 'partner')
);

INSERT INTO Users (Users_Id, Banned, Role) VALUES (1, 'No', 'client');
INSERT INTO Users (Users_Id, Banned, Role) VALUES (2, 'Yes', 'client');
INSERT INTO Users (Users_Id, Banned, Role) VALUES (3, 'No', 'client');
INSERT INTO Users (Users_Id, Banned, Role) VALUES (4, 'No', 'client');
INSERT INTO Users (Users_Id, Banned, Role) VALUES (10, 'No', 'driver');
INSERT INTO Users (Users_Id, Banned, Role) VALUES (11, 'No', 'driver');
INSERT INTO Users (Users_Id, Banned, Role) VALUES (12, 'No', 'driver');
INSERT INTO Users (Users_Id, Banned, Role) VALUES (13, 'No', 'driver');

 

五、解題SQL1

我一開始想的辦法比較複雜,第3-7行的SQL查出每日的未被禁止的客戶提交的全部單據數量,第8-14行的SQL查出這些單據中以日爲單位每日由未被禁止的客戶取消的單據數量,在SELECT子句中計算取消率。

SELECT A.Request_at AS DAY,
       ROUND(IFNULL(B.CANCELLED / A.TOTAL, 0), 2) AS 'Cancellation Rate'
FROM   (SELECT COUNT(*) AS TOTAL, Request_at
        FROM   Trips T1, Users U1
        WHERE  T1.Client_Id = U1.Users_Id AND U1.Banned = 'No'
        GROUP  BY Request_at
        HAVING COUNT(*)) AS A
LEFT   JOIN (SELECT COUNT(*) AS CANCELLED, Request_at
             FROM   (SELECT DISTINCT T.Id, T.Request_at
                     FROM   Trips T, Users U
                     WHERE  T.Status <> 'completed' AND
                            T.Client_Id = U.Users_Id AND U.Banned = 'No') AS TMP
             GROUP  BY TMP.Request_at
             HAVING COUNT(*)) AS B ON A.Request_at = B.Request_at
WHERE  A.Request_at >= '2013-10-01' AND A.Request_at <= '2013-10-03';

六、解題SQL2

下面的SQL是一個比較簡單的方法,經過 LEFT JOIN 跨表查詢,並統計狀態不爲completed的出租車訂單。

SELECT Request_at DAY,
       ROUND(SUM(IF(Status = 'completed', 0, 1)) / COUNT(*), 2) 'Cancellation Rate'
FROM   Trips t
LEFT   JOIN Users t1 ON t.Client_Id = t1.Users_Id
WHERE  t1.Banned = 'No' AND Request_at BETWEEN '2013-10-01' AND '2013-10-03'
GROUP  BY t.Request_at;

END

相關文章
相關標籤/搜索