# Write your MySQL query statement below
1972. 同一天的第一个电话和最后一个电话
表: Calls
+--------------+----------+ | Column Name | Type | +--------------+----------+ | caller_id | int | | recipient_id | int | | call_time | datetime | +--------------+----------+ (caller_id, recipient_id, call_time) 是这个表的主键。 每一行所含的时间信息都是关于caller_id 和recipient_id的。
编写一个 SQL 查询来找出那些ID们在任意一天的第一个电话和最后一个电话都是和同一个人的。这些电话不论是拨打者还是接收者都会被记录。
结果请放在一个任意次序约束的表中。
查询结果格式如下所示:
输入: Calls table: +-----------+--------------+---------------------+ | caller_id | recipient_id | call_time | +-----------+--------------+---------------------+ | 8 | 4 | 2021-08-24 17:46:07 | | 4 | 8 | 2021-08-24 19:57:13 | | 5 | 1 | 2021-08-11 05:28:44 | | 8 | 3 | 2021-08-17 04:04:15 | | 11 | 3 | 2021-08-17 13:07:00 | | 8 | 11 | 2021-08-17 22:22:22 | +-----------+--------------+---------------------+ 输出: +---------+ | user_id | +---------+ | 1 | | 4 | | 5 | | 8 | +---------+ 解释: 在 2021-08-24,这天的第一个电话和最后一个电话都是在user 8和user 4之间。user8应该被包含在答案中。 同样的,user 4在2 021-08-24 的第一个电话和最后一个电话都是和user 8的。user 4也应该被包含在答案中。 在 2021-08-11,user 1和5有一个电话。这个电话是他们彼此当天的唯一一个电话。因此这个电话是他们当天的第一个电话也是最后一个电话,他们都应该被包含在答案中。
原站题解
mysql 解法, 执行用时: 233 ms, 内存消耗: 0 B, 提交时间: 2023-10-16 17:03:04
SELECT DISTINCT u1 user_id FROM ( SELECT u1, u2, dt FROM ( SELECT # 2. 用户一天内通话行为的时间先后 u1, u2, DATE(call_time) dt, ROW_NUMBER() OVER(PARTITION BY u1, DATE(call_time) ORDER BY call_time asc) rk_asc, ROW_NUMBER() OVER(PARTITION BY u1, DATE(call_time) ORDER BY call_time desc) rk_desc FROM ( # 1. 列出用户所有的通话行为(呼出,或接听) SELECT caller_id u1, recipient_id u2, call_time FROM Calls UNION ALL SELECT recipient_id u1, caller_id u2, call_time FROM Calls) t1) t2 WHERE rk_asc = 1 or rk_desc = 1 # 3. 筛选出用户一天内的第一通和最后一通通话 ) t3 GROUP BY u1, dt # 4. 按用户日期聚合 HAVING COUNT(DISTINCT u2) = 1 # 5. 筛选出一天内,第一通和最后一通电话都为同一人的记录。
mysql 解法, 执行用时: 245 ms, 内存消耗: 0 B, 提交时间: 2023-10-16 17:02:43
# Write your MySQL query statement below with a as ( SELECT caller_id, recipient_id, call_time FROM Calls UNION ALL SELECT recipient_id caller_id, caller_id recipient_id, call_time FROM Calls ) SELECT DISTINCT a.caller_id user_id FROM (SELECT caller_id, recipient_id, dense_rank() over (PARTITION BY caller_id, DATE_FORMAT(call_time, '%Y-%m-%d') order by call_time) AS rk FROM a) a INNER JOIN (SELECT caller_id, recipient_id, dense_rank() over (PARTITION BY caller_id, DATE_FORMAT(call_time, '%Y-%m-%d') order by call_time DESC) AS rk FROM a) b ON a.caller_id = b.caller_id AND a.recipient_id = b.recipient_id AND a.rk = 1 AND b.rk = 1