题目描述

(通过次数32,630 | 提交次数60,307,通过率54.11%)

Table:Activity
+--------------+---------+
| Column Name  | Type    |
+--------------+---------+
| player_id    | int     |
| device_id    | int     |
| event_date   | date    |
| games_played | int     |
+--------------+---------+
(player_id, event_date) 是这个表的两个主键
这个表显示的是某些游戏玩家的游戏活动情况
每一行是在某天使用某个设备登出之前登录并玩多个游戏(可能为0)的玩家的记录
请编写一个 SQL 查询,描述每一个玩家首次登陆的设备名称

查询结果格式在以下示例中:

Activity table:
+-----------+-----------+------------+--------------+
| player_id | device_id | event_date | games_played |
+-----------+-----------+------------+--------------+
| 1         | 2         | 2016-03-01 | 5            |
| 1         | 2         | 2016-05-02 | 6            |
| 2         | 3         | 2017-06-25 | 1            |
| 3         | 1         | 2016-03-02 | 0            |
| 3         | 4         | 2018-07-03 | 5            |
+-----------+-----------+------------+--------------+
Result table:
+-----------+-----------+
| player_id | device_id |
+-----------+-----------+
| 1         | 2         |
| 2         | 3         |
| 3         | 1         |
+-----------+-----------+

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/game-play-analysis-ii
//测试数据
Create table If Not Exists Activity (player_id int, device_id int, event_date date, games_played int);

insert into Activity (player_id, device_id, event_date, games_played) values ('1', '2', '2016-03-01', '5');
insert into Activity (player_id, device_id, event_date, games_played) values ('1', '2', '2016-05-02', '6');
insert into Activity (player_id, device_id, event_date, games_played) values ('2', '3', '2017-06-25', '1');
insert into Activity (player_id, device_id, event_date, games_played) values ('3', '1', '2016-03-02', '0');
insert into Activity (player_id, device_id, event_date, games_played) values ('3', '4', '2018-07-03', '5');

解题思路

Activity表保存了每个用户每天的登录信息。

题目要求:查询每个用户最早登录的device_id。

很明显,这是求分组内极小值的问题。

一般来说,可以使用子查询或窗口函数实现。

实现思路都是先使用player_id分组,求出最小的event_date,然后筛选出最小的event_date所在的行即可。

参考SQL

未特别说明的情况下,参考SQL为基于MySQL8.0实现。
select
    player_id,
    device_id
from Activity
where (player_id,event_date) in (
    select
        player_id,
        min(event_date)
    from Activity
    group by player_id
);
picture loss