订阅更新

玩家首次登录日期:MIN 比窗口函数更省事

SQL 实战 123 题 · 第 14 题 简单 约 2 分钟读完

LeetCode 511 · 分组取最小值、窗口排名

本文目录
  1. 面试怎么回答
  2. 题意
  3. 表结构
  4. 思路
  5. 参考解法
  6. 易错点

面试怎么回答

只要首次登录日期,直接 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 更快也更好读。
刷题进度保存在当前浏览器