列表

详情


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有一个电话。这个电话是他们彼此当天的唯一一个电话。因此这个电话是他们当天的第一个电话也是最后一个电话,他们都应该被包含在答案中。

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
# Write your MySQL query statement below

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

上一题