LeetCode--512. 游戏玩法分析 II

1 题目描述

Table: Activity

+--------------+---------+
| Column Name  | Type    |
+--------------+---------+
| player_id    | int     |
| device_id    | int     |
| event_date   | date    |
| games_played | int     |
+--------------+---------+

(player_id, event_date) 是这个表的两个主键(具有唯一值的列的组合)
这个表显示的是某些游戏玩家的游戏活动情况
每一行是在某天使用某个设备登出之前登录并玩多个游戏(可能为0)的玩家的记录

1.1 测试用例

请编写解决方案,描述每一个玩家首次登陆的设备名称

返回结果格式如以下示例:

示例 1:
输入:

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            |
+-----------+-----------+------------+--------------+

输出:

+-----------+-----------+
| player_id | device_id |
+-----------+-----------+
| 1         | 2         |
| 2         | 3         |
| 3         | 1         |
+-----------+-----------+

2 解题思路

2.1 踩坑思路

这题看上去与 LeetCode–511. 游戏玩法分析 I 相似, 但用到的思想有一定的差异, 一开始想借用这题的思路找到结果

select a.player_id, a.device_id from (select player_id, device_id, min(event_date) as first_login from Activity group by player_id) a

测试用用例

| player_id | device_id | event_date | games_played |
| --------- | --------- | ---------- | ------------ |
| 1         | 2         | 2016-03-01 | 5            |
| 1         | 2         | 2016-05-02 | 6            |
| 1         | 3         | 2015-06-25 | 1            |
| 3         | 1         | 2016-03-02 | 0            |
| 3         | 4         | 2016-02-03 | 5            |

预期结果

| player_id | device_id |
| --------- | --------- |
| 1         | 3         |
| 3         | 4         |

实际输出

| player_id | device_id |
| --------- | --------- |
| 1         | 2         |
| 3         | 1         |

上面的 sql 有坑, 在 group by player_idmin(event_date) 条件下, device_id 不是 min(event_date) 这行对应的数据

2.2 min() + join

解题思路

  1. group by player_idmin(event_date) 通过这个查找每个 player_id 的最早登录时间
  2. 使用 join 外连接 Activity, 连接条件 player_idevent_date
select a.player_id, a.device_id  
from Activity as a  
         inner join (select player_id, min(event_date) as event_date from Activity group by player_id) as b  
                    on a.player_id = b.player_id and a.event_date = b.event_date

2.3 rank() + over()

解题思路

  1. 使用 rank() + over() 组合函数实现, 按照 player_id 分组, 查询最早登录的 event_datedevice_id
  2. 对上面结果进行筛选, 查找出 rank = 1 的数据
select a.player_id, a.device_id  
from (select player_id, device_id, rank() over (partition by player_id order by event_date) as 'rank' from Activity) a  
where a.rank = 1
  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值