题目描述
(通过次数8,868 | 提交次数11,509,通过率77.05%)
表: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。 以 任意顺序 返回结果表。 查询结果格式如下示例所示。 示例 1: 输入: 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)。 来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/number-of-calls-between-two-persons
//测试数据 Create table If Not Exists Calls (from_id int, to_id int, duration int); insert into Calls (from_id, to_id, duration) values ('1', '2', '59'); insert into Calls (from_id, to_id, duration) values ('2', '1', '11'); insert into Calls (from_id, to_id, duration) values ('1', '3', '20'); insert into Calls (from_id, to_id, duration) values ('3', '4', '100'); insert into Calls (from_id, to_id, duration) values ('3', '4', '200'); insert into Calls (from_id, to_id, duration) values ('3', '4', '200'); insert into Calls (from_id, to_id, duration) values ('4', '3', '499');
解题思路
Calls表中保存了每一笔通话信息。包括拨出方、接收方、通话时长。
题目要求:统计每两个用户之间的通话记录汇总。因为A与B和B与A的通话记录统计结果是相同的,因此,题目要求返回的结果中,只返回一种组合即可(即:用户ID较小的放在左边,较大的放在右边)。
也就是说,一条通话记录只会被记录一次。
Calls表通话记录中,拨出方的用户ID有可能较小,接收方的用户ID也有可能较小。那么,我们可以先对通话记录进行标准化:把拨出方和接收方中用户ID较小的那一个放在第一字段,较大的那一个放在第二个字段。这就与题目要求的返回结果相同了,然后再直接使用GROUP BY+COUNT+SUM汇总即可。
参考SQL
未特别说明的情况下,参考SQL为基于MySQL8.0实现。
select person1, person2, count(1) call_count, sum(duration) total_duration from ( select case when from_id < to_id then from_id else to_id end person1, case when from_id < to_id then to_id else from_id end person2, duration from Calls )a group by person1, person2;
本站所有内容均为原创,本站保留所有权利。仅允许非商业用途的转载,但必须注明来源网站、作者、来源链接!否则,由此造成的一切后果,由转载方承担!
干货分享、技术提升、面试笔试、学习交流,欢迎关注公众号:xuesql。QQ学习交流群:209942678。