❤️博客主页: 楚生辉
❤️系列专栏:【LeetCode刷题】
❤️一句短话: 坚持不懈,孜孜不倦
1.题目描述
员工表:Calls
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| from_id | int |
| to_id | int |
| duration | int |
+-------------+---------+
该表没有主键,可能存在重复项。
该表包含 from_id 与 to_id 间的一次电话的时长。
from_id != to_id
编写 SQL 语句,查询每一对用户 (person1, person2) 之间的通话次数和通话总时长,其中 person1 < person2 。
以 任意顺序 返回结果表。
查询结果格式如下示例所示。
输入:
Calls 表:
+---------+-------+----------+
| from_id | to_id | duration |
+---------+-------+----------+
| 1 | 2 | 59 |
| 2 | 1 | 11 |
| 1 | 3 | 20 |
| 3 | 4 | 100 |
| 3 | 4 | 200 |
| 3 | 4 | 200 |
| 4 | 3 | 499 |
+---------+-------+----------+
输出:
+---------+---------+------------+----------------+
| person1 | person2 | call_count | total_duration |
+---------+---------+------------+----------------+
| 1 | 2 | 2 | 70 |
| 1 | 3 | 1 | 20 |
| 3 | 4 | 4 | 999 |
+---------+---------+------------+----------------+
解释:
用户 1 和 2 打过 2 次电话,总时长为 70 (59 + 11)。
用户 1 和 3 打过 1 次电话,总时长为 20。
用户 3 和 4 打过 4 次电话,总时长为 999 (100 + 200 + 200 + 499)。
2.代码实现
- 方法一:巧妙使用IF
观察Calls,我们发现如果
from_id与to_id之前永远是前面小与后面的,那么这一道题就会变得非常的简单,因此我们可以使用IF判断来实现from_id与to_id的顺序调转
SELECT
IF(from_id<to_id,from_id,to_id) person1,
IF(from_id>to_id,from_id,to_id) person2,
COUNT(to_id ) as call_count,
SUM(duration) as total_duration
FROM
Calls
GROUP BY person1,person2
- 方法二:自联结
select
from_id person1,
to_id person2,
count(1) call_count,
sum(duration) total_duration
from
(
select * from Calls where from_id < to_id
union all
select to_id from_id,from_id to_id,duration from Calls where from_id > to_id
) t
group by
1,2
order by
1,2

被折叠的 条评论
为什么被折叠?



