comments | difficulty | edit_url | tags | |
---|---|---|---|---|
true |
中等 |
|
表:Contacts
+-------------+---------+ | Column Name | Type | +-------------+---------+ | id | int | | first_name | varchar | | last_name | varchar | +-------------+---------+ id 是这张表的主键(有不同值的列)。 id 是 Calls 表的外键(引用列)。 这张表的每一行都包含 id,first_name 和 last_name。
表:Calls
+-------------+------+ | Column Name | Type | +-------------+------+ | contact_id | int | | type | enum | | duration | int | +-------------+------+ (contact_id, type, duration) 是这张表的主键(有不同值的列)。 type 字段是 ('incoming', 'outgoing') 的 ENUM (category)。 这张表的每一行包含有 calls, 包括 contact_id,type 和以秒为单位的 duration 的信息。
编写一个解决方案来找到 三个最长的呼入 和 呼出 电话。
返回结果表,以 type
,duration
和 first_name
降序排序 ,duration
的格式必须为 HH:MM:SS。
结果格式如下所示。
示例 1:
输入:
Contacts 表:
+----+------------+-----------+ | id | first_name | last_name | +----+------------+-----------+ | 1 | John | Doe | | 2 | Jane | Smith | | 3 | Alice | Johnson | | 4 | Michael | Brown | | 5 | Emily | Davis | +----+------------+-----------+
Calls 表:
+------------+----------+----------+ | contact_id | type | duration | +------------+----------+----------+ | 1 | incoming | 120 | | 1 | outgoing | 180 | | 2 | incoming | 300 | | 2 | outgoing | 240 | | 3 | incoming | 150 | | 3 | outgoing | 360 | | 4 | incoming | 420 | | 4 | outgoing | 200 | | 5 | incoming | 180 | | 5 | outgoing | 280 | +------------+----------+----------+
输出:
+-----------+----------+-------------------+ | first_name| type | duration_formatted| +-----------+----------+-------------------+ | Michael | incoming | 00:07:00 | | Jane | incoming | 00:05:00 | | Emily | incoming | 00:03:00 | | Alice | outgoing | 00:06:00 | | Emily | outgoing | 00:04:40 | | Jane | outgoing | 00:04:00 | +-----------+----------+-------------------+
解释:
- Michael 有一通长达 7 分钟的呼入电话。
- Jane 有一通长达 5 分钟的呼入电话。
- Emily 有一通长达 3 分钟的呼入电话。
- Alice 有一通长达 6 分钟的呼出电话。
- Emily 有一通长达 4 分 40 秒的呼出电话。
- Jane 有一通长达 4 分钟的呼出电话。
注意:输出表以 type,duration 和 first_name 降序排序。
我们可以使用等值连接将两张表连接起来,然后使用窗口函数 RANK()
计算每个类型的电话的排名。最后,我们只需要筛选出排名前三的电话即可。
WITH
T AS (
SELECT
first_name,
type,
DATE_FORMAT(SEC_TO_TIME(duration), "%H:%i:%s") AS duration_formatted,
RANK() OVER (
PARTITION BY type
ORDER BY duration DESC
) AS rk
FROM
Calls AS c1
JOIN Contacts AS c2 ON c1.contact_id = c2.id
)
SELECT
first_name,
type,
duration_formatted
FROM T
WHERE rk <= 3
ORDER BY 2, 3 DESC, 1 DESC;
import pandas as pd
def find_longest_calls(contacts: pd.DataFrame, calls: pd.DataFrame) -> pd.DataFrame:
merged_data = calls.merge(contacts, left_on="contact_id", right_on="id")
merged_data["duration_formatted"] = (
merged_data["duration"] // 3600 * 10000
+ merged_data["duration"] % 3600 // 60 * 100
+ merged_data["duration"] % 60
).apply(lambda x: "{:02}:{:02}:{:02}".format(x // 10000, x // 100 % 100, x % 100))
merged_data["rk"] = merged_data.groupby("type")["duration"].rank(
method="dense", ascending=False
)
result = merged_data[merged_data["rk"] <= 3][
["first_name", "type", "duration_formatted"]
]
result = result.sort_values(
by=["type", "duration_formatted", "first_name"], ascending=[True, False, False]
)
return result