• 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

  • 相关阅读:
    深度优先搜索和广度优先搜索
    el-table 实现表、表格行、表格列合并
    直接插入排序算法详解之C语言版
    有限元学习笔记-传热及流体力学问题
    java基础面试:继承、final关键字、抽象类、接口
    设计模式之观察者模式
    系统架构设计师学习笔记——软件工程
    基于RBF神经网络的非线性系统识别(Matlab代码实现)
    Go基础18-理解方法的本质以选择正确的receiver类型
    mysql的if语句,如何在if不成立的时候不执行操作
  • 原文地址:https://blog.csdn.net/qq_40752621/article/details/126532785