【发布时间】:2022-01-16 12:54:52
【问题描述】:
我正在解决以下 Hard Leetcode SQL 问题。
问题链接: https://leetcode.com/problems/trips-and-users/
问题:
+-------------+----------+
| Column Name | Type |
+-------------+----------+
| id | int |
| client_id | int |
| driver_id | int |
| city_id | int |
| status | enum |
| request_at | date |
+-------------+----------+
id is the primary key 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 type of ('completed', 'cancelled_by_driver', 'cancelled_by_client').
+-------------+----------+
| Column Name | Type |
+-------------+----------+
| users_id | int |
| banned | enum |
| role | enum |
+-------------+----------+
users_id is the primary key 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 type of ('Yes', 'No').
取消率的计算方法是将取消(由客户或司机)取消禁止用户的请求数除以当天取消禁止用户的请求总数。
编写一个 SQL 查询,查找“2013-10-01”和“2013-10-03”之间每天未禁止用户(客户端和驱动程序均不得禁止)的请求的取消率。取消率四舍五入到小数点后两位。
以任意顺序返回结果表。
查询结果格式如下例。
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 |
+------------+-------------------+
这是我的代码:
WITH Requests_Cancelled AS (
SELECT Trips.client_id as ID, Trips.request_at as Day, COUNT(*) as cancelled_count
FROM Trips
INNER JOIN Users ON
Trips.client_id = Users.users_id
WHERE Users.banned = "No" AND Users.role = "client" AND Trips.status = "cancelled_by_client"
GROUP BY Trips.request_at
UNION
SELECT Trips.driver_id as ID, Trips.request_at as Day, COUNT(*) as cancelled_count
FROM Trips
INNER JOIN Users ON
Trips.driver_id = Users.users_id
WHERE Users.banned = "No" AND Users.role = "driver" AND Trips.status = "cancelled_by_driver"
GROUP BY Trips.request_at
),
Requests_Total AS (
SELECT Trips.client_id as ID, Trips.request_at as Day, COUNT(*) as total_count
FROM Trips
INNER JOIN Users ON
Trips.client_id = Users.users_id
WHERE Users.banned = "No" AND Users.role = "client"
GROUP BY Trips.request_at
UNION
SELECT Trips.driver_id as ID, Trips.request_at as Day, COUNT(*) as total_count
FROM Trips
INNER JOIN Users ON
Trips.driver_Id = Users.users_id
WHERE Users.banned = "No" AND Users.role = "driver"
GROUP BY Trips.request_at
)
SELECT Requests_Total.Day, IFNULL(MAX(ROUND(Requests_Cancelled.cancelled_count/Requests_Total.total_count, 2)), 0) as 'Cancellation Rate'
FROM Requests_Cancelled
RIGHT JOIN Requests_Total ON
Requests_Cancelled.Day = Requests_Total.Day
GROUP BY Requests_Total.Day
ORDER BY Requests_Total.Day ASC;
代码通过了下面的第一个测试用例:
输入: {"headers": {"Trips": ["id", "client_id", "driver_id", "city_id", "status", "request_at"], "Users ": ["users_id", "banned", "role"]}, "rows": {"Trips": [["1", "1", "10", "1", "completed", "2013 -10-01"], ["2", "2", "11", "1", "cancelled_by_driver", "2013-10-01"], ["3", "3", "12", “6”、“完成”、“2013-10-01”]、[“4”、“4”、“13”、“6”、“cancelled_by_client”、“2013-10-01”]、[“5 ", "1", "10", "1", "完成", "2013-10-02"], ["6", "2", "11", "6", "完成", "2013 -10-02"], ["7", "3", "12", "6", "完成", "2013-10-02"], ["8", "2", "12", “12”、“完成”、“2013-10-03”]、[“9”、“3”、“10”、“12”、“完成”、“2013-10-03”]、[“10 ", "4", "13", "12", "cancelled_by_driver", "2013-10-03"]], "用户": [["1", "No", "client"], ["2 ", "Yes", "client"], ["3", "No", "client"], ["4", "No", "client"], ["10", "No", "driver "], ["11", "No", "driver"], ["12", "No", "driver"], ["13", "No", "driver"]]}}
输出: {"headers": ["Day", "Cancellation Rate"], "values": [["2013-10-01", 0.33], ["2013-10 -02", 0.00], ["2013-10-03", 0.50]]}
预期: {"headers": ["Day", "Cancellation Rate"], "values": [["2013-10-01", 0.33], ["2013-10 -02", 0.00], ["2013-10-03", 0.50]]}
但没有通过第二个测试用例:
输入: {"headers": {"Trips": ["id", "client_id", "driver_id", "city_id", "status", "request_at"], "Users ": ["users_id", "banned", "role"]}, "rows": {"Trips": [["1", "1", "10", "1", "cancelled_by_client", "2013 -10-04"]], "用户": [["1", "No", "client"], ["10", "No", "driver"]]}}
输出: {"headers": ["Day", "Cancellation Rate"], "values": [["2013-10-04", 1.00]]}
预期: {"headers":["Day","Cancellation Rate"],"values":[]}
我不明白为什么在第二个测试用例中需要 NULL 值。
【问题讨论】:
-
我有一个解决方案,并添加了关于您的代码为何未能通过测试用例的解释。你几乎步入正轨。在您的代码中,您应该为每次行程验证司机和客户均未禁止。相反,您的代码会检查未禁止客户的游乐设施(即使司机可能被禁止),并添加到未禁止司机的游乐设施(即使可能禁止客户)。
-
感谢@zedfoxus 在下面的详细解释!欣赏它!为你干杯!
-
绝对!你是如此接近。把写得好的问题和你的代码一起归功于自己。干得好。
标签: mysql sql common-table-expression