MySQL之窗口函数

MySQL之窗口函数

名称 参数 描述
ROW_NUMBER() 当前行在其分组内的序号。不管其排序结果是否出现重复值,其排序结果均为:1,2,3,4,5…
DENSE_RANK() 不间断的组内排序,排序结果(可能)为:1,2,2,3,4,4…
RANK() 间断的组内排序,排序结果(可能)为:1,1,3,4,4,6…
PERCENT_RANK() 累计百分比,计算结果为:小于该条记录值的所有记录的行数/该分组的总行数-1 所以该记录的返回值为[0,1]
CUME_DIST() 累计分布值,分组值小于等于当前值的行数与分组总行数的比值,取值范围为[0,1]
LAG(expr,[N,[default]]) 从当前行开始往取第N行,如果N缺失,默认为1,如果不存在前一行,则默认返回default,default默认值为NULL
LEAG(expr,[N,[default]]) 从当前行开始往取第N行,如果N缺失,默认为1,如果不存在前一行,则默认返回default,default默认值为NULL
FIRST_VALUE(expr) 返回分组内截止当前行的第一个值
LAST_VALUE(expr) 返回分组内截止当前行的最后一个值
NTH_VALUE(expr,N) 返回当前分组内截止当前行的第N行
NTILE(N) 返回当前分组内的分桶好,在计算时要先将该分组内的所有数据划分成N个桶,之后返回每个记录所在的分桶号,返回范围从1到

格式

窗口函数([<字段名>])over([partition by <分组字段>] [order by <排序字段>[desc]] [<窗口分区>])

partition by子句:按照指定字段进行分区,两个分区由边界分隔,窗口函数在不同的分区内分别执行,在跨越分区边界时重新初始化。

order by子句:按照指定字段进行排序,窗口函数将按照排序后的记录顺序进行编号。可以和partition by子句配合使用,也可以单独使用。

frame子句:当前分区的一个子集,用来定义子集的规则,通常用来作为滑动窗口使用。

实例力扣

作者:zg104
链接:https://leetcode.cn/problems/game-play-analysis-ii/solution/by-zg104-xt7d/
来源:力扣(LeetCode)

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

题解

在本题中,要找到每位玩家第一次登录的设备id,则需要对玩家id进行分组,每组求ROW_NUMBER,使用ROW_NUMBER而不使用其他窗口函数的原因是ROW_NUMBER结果是不重复的,适合本题的场景

select
player_id, device_id
from
(
select
player_id,
device_id,
dense_rank() over(partition by player_id
order by event_date asc) rnk
from activity
) a where rnk=1

你可能感兴趣的:(mysql,数据库)