玩家首次登录日期:MIN 比窗口函数更省事
LeetCode 511 · 分组取最小值、窗口排名
面试怎么回答
只要首次登录日期,直接 GROUP BY player_id 取 MIN(event_date)。如果还要首次登录那一行的其他字段,比如设备,我才会用 ROW_NUMBER 按日期排序取第一行。
先把这段讲顺;面试官追问时,再展开下面的原理和细节。
详细讲解
题意
活动表记录了玩家每天的登录情况(玩家、设备、日期、当天玩的游戏数)。求每个玩家第一次登录的日期。
表结构
- Activity:player_id、device_id、event_date、games_played;(player_id, event_date) 为主键
思路
只要日期本身,按玩家分组取 MIN(event_date) 就够了。窗口函数排名的写法也能得到结果,但多了一次排序和一层子查询;当题目还要同一行的其他字段(比如首次登录用的设备)时,窗口函数才更有必要。
参考解法
写法 1:窗口排名,取每个玩家最早的那天
select player_id ,event_date first_login
from (
select player_id ,event_date,
rank() over(partition by player_id order by event_date) rk
from Activity
) tmp
where rk = 1
写法 2:直接取最小日期,更简洁
select player_id ,min(event_date) first_login
from Activity
group by player_id
易错点
- 只要一个聚合值时不必上窗口函数,简单的 GROUP BY 更快也更好读。