【MySQL】MySQL 8.0 新特性之 - 窗口函数(Window Functions)

news2025/1/18 9:47:12

窗口函数 - Window Functions

  • 1. 定义
    • 1.1 窗口函数
    • 1.2 语法格式
  • 2. 分类
    • 2.1 序号函数
      • 2.1.1 row_number()
      • 2.1.2 rank()
      • 2.1.3 dense_rank()
      • 2.2.4 示例
    • 2.2 分布函数
      • 2.2.1 percent_rank()
      • 2.2.2 cume_dist()
    • 2.3 前后函数
      • 2.3.1 lag(expr, n, default)
      • 2.3.2 lead(expr, n, default)
      • 2.3.3 示例
    • 2.4 头尾函数
      • 2.4.1 first_value(expr)
      • 2.4.2 last_value(expr)
      • 2.4.3 示例
    • 2.5 其他函数
      • 2.5.1 nth_value(expr, n)
      • 2.5.2 ntile(n)
      • 2.5.3 示例
    • 2.6 聚合类窗口函数

1. 定义

1.1 窗口函数

官网地址:https://dev.mysql.com/doc/refman/8.0/en/window-functions.html

窗口可以理解为记录集合,窗口函数就是在满足某种条件的记录集合上执行的特殊函数。
即:每条记录都要在此窗口内执行函数

  • 静态窗口:每条记录都要在此窗口内执行函数,窗口大小都是固定的

  • 动态窗口:不同的记录对应着不同的窗口,这种动态变化的窗口叫滑动窗口。

窗口函数也称为 OLAP(Online Anallytical Processing)函数,意思是对数据库数据进行实时分析处理。窗口函数就是为了实现 OLAP 而添加的标准 SQL 功能。

窗口函数对一组查询行执行类似聚合的操作。然而,聚合操作将查询行分组为单个结果行,而窗口函数为每个查询行生成一个结果

  • 发生函数计算的行称为当前行。

  • 与对其进行函数计算的当前行相关的查询行构成当前行的窗口。

在这里插入图片描述

1.2 语法格式

函数名(字段名) over(子句);

over 括号内若不写,则意味着窗口函数基于满足 where 条件的所有行进行计算;

若括号内不为空,则支持以下语法来设置窗口:

函数名(字段名) over(partition by <要分列的组> order by <要排序的列> rows between <数据范围>) 

数据范围:

# 取本行和前面两行
rows between 2 preceding and current row

# 取本行和之前所有的行
rows between unbounded preceding and current row

# 取本行和之后所有的行
rows between current row and unbounded following 

# 从前面三行和下面一行,总共五行
rows between 3 preceding and 1 following 

# 当 order by 后面没有 rows between 时,窗口规范默认是取本行和之前所有的行

# 当 order by 和 rows between 都没有时,窗口规范默认是分组下所有行 (rows between unbounded preceding and unbounded following)

2. 分类

2.1 序号函数

序号函数是按照一定的分组规则对每一组的数据排序并创建一个序号列。

2.1.1 row_number()

单纯的对每一组数据编号,进行顺序显示。

2.1.2 rank()

排序每一组的某一字段, 同等级同序号前后不连续。

对序号进行并列排序,指定字段数值相同(同一等级),则会产生相同序号记录,且产生序号间隙。

rank 函数没有参数,但需要指定按照那个字段进行排名,所以使用 rank 函数必须用 order by 参数,order by 的排序字段就是排名字段。

2.1.3 dense_rank()

排序每一组的某一字段, 同等级同序号前后也连续。

对序号进行并列排序,指定字段数值相同(同一等级)则会产生相同序号记录,且产生序号间隙。

2.2.4 示例

# 查询显示列中一组值的每个成员的排名值 val
mysql> SELECT
         val,
         ROW_NUMBER() OVER w AS 'row_number',
         RANK()       OVER w AS 'rank',
         DENSE_RANK() OVER w AS 'dense_rank'
       FROM numbers
       WINDOW w AS (ORDER BY val);
+------+------------+------+------------+
| val  | row_number | rank | dense_rank |
+------+------------+------+------------+
|    1 |          1 |    1 |          1 |
|    1 |          2 |    1 |          1 |
|    2 |          3 |    3 |          2 |
|    3 |          4 |    4 |          3 |
|    3 |          5 |    4 |          3 |
|    3 |          6 |    4 |          3 |
|    4 |          7 |    7 |          4 |
|    4 |          8 |    7 |          4 |
|    5 |          9 |    9 |          5 |
+------+------------+------+------------+

2.2 分布函数

分布函数有:percent_rank()、cume_dist()

2.2.1 percent_rank()

计算分区或结果集中行的百分位数排名。

每行按照公式 (rank-1)/ (rows-1) 进行计算。其中,rank 为 RANK() 函数产生的序号,rows 为当前窗口(当前组)的总行数。

2.2.2 cume_dist()

累积分布值,<= 当前 rank 值的行数 / 分组内总行数,取值范围为 0~1。

应用场景:查询小于等于当前成绩(score)的比例。

示例:

mysql> SELECT
         val,
         ROW_NUMBER()   OVER w AS 'row_number',
         CUME_DIST()    OVER w AS 'cume_dist',
         PERCENT_RANK() OVER w AS 'percent_rank'
       FROM numbers
       WINDOW w AS (ORDER BY val);
+------+------------+--------------------+--------------+
| val  | row_number | cume_dist          | percent_rank |
+------+------------+--------------------+--------------+
|    1 |          1 | 0.2222222222222222 |            0 |
|    1 |          2 | 0.2222222222222222 |            0 |
|    2 |          3 | 0.3333333333333333 |         0.25 |
|    3 |          4 | 0.6666666666666666 |        0.375 |
|    3 |          5 | 0.6666666666666666 |        0.375 |
|    3 |          6 | 0.6666666666666666 |        0.375 |
|    4 |          7 | 0.8888888888888888 |         0.75 |
|    4 |          8 | 0.8888888888888888 |         0.75 |
|    5 |          9 |                  1 |            1 |
+------+------------+--------------------+--------------+

2.3 前后函数

2.3.1 lag(expr, n, default)

返回当前行前 n 行的 expr 值。n 如果没有这样的行,则返回值为 default。如果缺少 n 或 default,则默认值分别为 1 或 NULL。

n 必须是非负整数。如果 n 为 0, expr 则为当前行的值。

从 MySQL 8.0.22 开始,n 不能 NULL。此外,它必须是1 到 2的63次方 的整数。

2.3.2 lead(expr, n, default)

返回当前行后 n 行的 expr 值。n 如果没有这样的行,则返回值为 default。如果缺少 n 或 default,则默认值分别为 1 或 NULL。

n 必须是非负整数。如果 n 为 0, expr 则为当前行的值。

从 MySQL 8.0.22 开始,n 不能 NULL。此外,它必须是1 到 2的63次方 的整数。

2.3.3 示例

mysql> SELECT
         t, val,
         LAG(val)        OVER w AS 'lag',
         LEAD(val)       OVER w AS 'lead',
         val - LAG(val)  OVER w AS 'lag diff',
         val - LEAD(val) OVER w AS 'lead diff'
       FROM series
       WINDOW w AS (ORDER BY t);
+----------+------+------+------+----------+-----------+
| t        | val  | lag  | lead | lag diff | lead diff |
+----------+------+------+------+----------+-----------+
| 12:00:00 |  100 | NULL |  125 |     NULL |       -25 |
| 13:00:00 |  125 |  100 |  132 |       25 |        -7 |
| 14:00:00 |  132 |  125 |  145 |        7 |       -13 |
| 15:00:00 |  145 |  132 |  140 |       13 |         5 |
| 16:00:00 |  140 |  145 |  150 |       -5 |       -10 |
| 17:00:00 |  150 |  140 |  200 |       10 |       -50 |
| 18:00:00 |  200 |  150 | NULL |       50 |      NULL |
+----------+------+------+------+----------+-----------+

2.4 头尾函数

2.4.1 first_value(expr)

first_value 取分组内排序后,截止到当前行,第一个值。

2.4.2 last_value(expr)

last_value 取分组内排序后,截止到当前行,最后一个值。

2.4.3 示例

mysql> SELECT
         time, subject, val,
         FIRST_VALUE(val)  OVER w AS 'first',
         LAST_VALUE(val)   OVER w AS 'last',
         NTH_VALUE(val, 2) OVER w AS 'second',
         NTH_VALUE(val, 4) OVER w AS 'fourth'
       FROM observations
       WINDOW w AS (PARTITION BY subject ORDER BY time
                    ROWS UNBOUNDED PRECEDING);
+----------+---------+------+-------+------+--------+--------+
| time     | subject | val  | first | last | second | fourth |
+----------+---------+------+-------+------+--------+--------+
| 07:00:00 | st113   |   10 |    10 |   10 |   NULL |   NULL |
| 07:15:00 | st113   |    9 |    10 |    9 |      9 |   NULL |
| 07:30:00 | st113   |   25 |    10 |   25 |      9 |   NULL |
| 07:45:00 | st113   |   20 |    10 |   20 |      9 |     20 |
| 07:00:00 | xh458   |    0 |     0 |    0 |   NULL |   NULL |
| 07:15:00 | xh458   |   10 |     0 |   10 |     10 |   NULL |
| 07:30:00 | xh458   |    5 |     0 |    5 |     10 |   NULL |
| 07:45:00 | xh458   |   30 |     0 |   30 |     10 |     30 |
| 08:00:00 | xh458   |   25 |     0 |   25 |     10 |     30 |
+----------+---------+------+-------+------+--------+--------+

2.5 其他函数

2.5.1 nth_value(expr, n)

nth_value 函数返回第 n 行的 expr 值,没有则返回 null。

2.5.2 ntile(n)

ntile 函数将分区中的有序数据分为 n 个桶,记录桶编号。

2.5.3 示例

mysql> SELECT
         val,
         ROW_NUMBER() OVER w AS 'row_number',
         NTILE(2)     OVER w AS 'ntile2',
         NTILE(4)     OVER w AS 'ntile4'
       FROM numbers
       WINDOW w AS (ORDER BY val);
+------+------------+--------+--------+
| val  | row_number | ntile2 | ntile4 |
+------+------------+--------+--------+
|    1 |          1 |      1 |      1 |
|    1 |          2 |      1 |      1 |
|    2 |          3 |      1 |      1 |
|    3 |          4 |      1 |      2 |
|    3 |          5 |      1 |      2 |
|    3 |          6 |      2 |      3 |
|    4 |          7 |      2 |      3 |
|    4 |          8 |      2 |      4 |
|    5 |          9 |      2 |      4 |
+------+------------+--------+--------+

2.6 聚合类窗口函数

sum() over( partion by <要分列的组> order by <要排序的列> rows between <数据范围> )

count() over( partion by <要分列的组> order by <要排序的列> rows between <数据范围> )

avg() over( partion by <要分列的组> order by <要排序的列> rows between <数据范围> )

max() over( partion by <要分列的组> order by <要排序的列> rows between <数据范围> )

min() over( partion by <要分列的组> order by <要排序的列> rows between <数据范围> )

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/197795.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

致跟我一样苦恼的你们

2023年2月1日&#xff0c;我决定结束实习&#xff0c;回去准备春招和毕设。我把这个决定跟家人和朋友说时&#xff0c;他们似乎是有点不太赞同&#xff0c;他们觉得&#xff1a; “现在工作不好找&#xff0c;你可以先找好下一家公司后再选择离职” “毕设得事情&#xff0c;…

VBA提高篇_17 区域合纵连横,单元格精准定位

文章目录Application.Union方法:Application.Intersect方法:Range.CurrentRegion属性:Range.Resize(3,2)Range.Offset 单元格偏移属性Application.Union方法: 把多个Range联合在一起,作为一个新的Range对象返回 Sub RangeUnionDemo()Dim a&, r1 As Range, r2 As Range, r3 …

魔兽世界服务端AzerothCore+Centos系统+docker编译教程

魔兽世界服务端AzerothCoreCentos系统docker编译教程1.1 准备工作1.1.1 准备1.1.2 安装软件1.1.3 下载源码1.1.4 地图文件1.2 修改配置文件1.2.1 修改环境变量文件1.2.2 修改文件执行权限1.2.3 修改配置文件1.3 编译及启动1.3.1 编译项目1.3.2 启动容器1.3.3 无法启动1. 网络问…

【Java多线程】线程的安全问题

根据上篇文章买票问题举例&#xff0c;还可能出现的问题&#xff1a; 代码如下&#xff1a; class Window1 implements Runnable{private static int ticket 100;Overridepublic void run() {while (true){if (ticket > 0){try {Thread.sleep(100);} catch (InterruptedExc…

网站优化与seo的方法(seo的优化基础)

SEO优化的常规思路&#xff0c;别全以转化为目标 SEO优化作为现在公司推广营销的基础&#xff0c;几乎每个公司都在做这件事。这种优化既可以提升品牌知名度&#xff0c;又能直接给公司带来流量&#xff0c;确实让不少公司感觉很有用。但是在持续的过程中&#xff0c;又会觉得…

ESP32 Arduino 学习篇(五)TFT_eSPI库

前期准备&#xff1a;1.TFT_eSPI库的安装首先在Libraries里面搜索安装TFT_eSPI库到你的工程文件里面。2.TFT_eSPI库的配置文件配置该库有User_Setup.h和 User_Setup_Select.h两个配置文件&#xff0c;支持 ①自定义参数或 ②使用已有配置 驱动TFT屏幕。User_Setup.h — 由自己定…

PCB阻焊层介绍与设计经验总结

&#x1f3e1;《总目录》 目录1&#xff0c;什么是阻焊层2&#xff0c;阻焊层的用途,3&#xff0c;阻焊层的工艺流程4&#xff0c;阻焊设计的注意事项1&#xff0c;什么是阻焊层 阻焊层是顶层或底层布线层表面的顶层保护层&#xff0c;就是PCB表层的绿油层&#xff0c;在阻焊层…

【坤坤讲师--图】Dinic

Dinic是个很神奇的网络流算法。它是一个基于“层次图”的时间效率优先的最大流算法。层次图是什么东西呢?层次,其实就是从源点走到那个点的最短路径长度。于是乎,我们得到一个定理:从源点开始,在层次图中沿着边不管怎么走,经过的路径一定是终点在剩余图中的最短路。(摘自…

疫情时代的宠儿:抗生素行业,今后何去何从

本文由前嗅数据研究院出品 自2020年COVID-19流行开始&#xff0c;已经过去了3年&#xff0c;医药行业发生巨大的变化&#xff0c;各种大中小企业实现了一系列调整。疫情将近结束的时候&#xff0c;让我们回顾分析一下近年来医药领域抗生素行业相关发展。 本研究将从行业现状、…

SpringBoot+Vue核酸预约系统

简介&#xff1a;本项目采用了基本的springbootvue设计的核酸预约系统。详情请看截图。经测试&#xff0c;本项目正常运行。本项目适用于Java毕业设计、课程设计学习参考等用途。 项目描述 项目名称SpringBootVue核酸预约系统源码作者LHL项目类型Java EE项目 &#xff08;前后…

计算机网络基础知识总结

计算机网络基础知识总结 如果说计算机把我们从工业时代带到了信息时代&#xff0c;那么计算机网络就可以说把我们带到了网络时代。随着使用计算机人数的不断增加&#xff0c;计算机也经历了一系列的发展&#xff0c;从大型通用计算机 -> 超级计算机 -> 小型机 -> 个人…

Windows驱动环境配置

windows驱动开发视频教程(2023最新版)_哔哩哔哩_bilibili 以前的 WDK 版本和其他下载 - Windows drivers | Microsoft Learn 确认本机操作系统版本 安装操作系统版本对应的Visual Studio 我的机器是1904可以安装vs2019&#xff0c;但是实际上我装的是vs2017也是没有问题的 安…

泼辣修图2023最新网页版MAC电脑手机修图软件功能介绍

泼辣修图5.11.4最新版为用户带来更多新版的修改工具&#xff0c;进一步优化相关的设备&#xff0c;可以更舒畅的使用去修改图片&#xff0c;还有很多贴纸&#xff0c;文字等等小工具使用&#xff0c;丰富照片情景。 适用于Windows的泼辣修图摄影爱好者都在用泼辣处理照片 泼辣…

并发编程学习案例-ReentrantReadWriteLock非公平的情况下读锁插队和写锁插队场景复现

文章目录一、前言二、源码三、 代码案例&#xff08;一&#xff09;复现写的时候插队场景参考执行结果&#xff08;二&#xff09;复现读的时候插队参考执行结果参考资料一、前言 Java ReentrantReadWriteLock 是 ReadWriteLock 的实现类&#xff0c;可以分出2把锁&#xff0c;…

OpenCV 图像形态学处理

本文是OpenCV图像视觉入门之路的第11篇文章&#xff0c;本文详细的在图像形态学进行了图像处理&#xff0c;例如&#xff1a;腐蚀操作、膨胀操作、开闭运算、梯度运算、Top Hat Black Hat运算等操作。 OpenCV 图像形态学处理目录 1 腐蚀操作 2 膨胀操作 3 开闭运算 4 梯度运…

57.Isaac教程--定位监视器

定位监视器 ISAAC教程合集地址: https://blog.csdn.net/kunhe0512/category_12163211.html 检测异常系统状态并采取纠正措施有助于确保稳定的系统性能和与预期行为的最小偏差。 为此&#xff0c;Isaac SDK 提供了一个监控框架&#xff0c;可以搭载多种系统观察组件。 该框架目…

达芬奇18.1.2软件更新内容及安装教程(WinMac)

DaVinci Resolve v18.1.2是一款在同一个软件工具中&#xff0c;将剪辑、调色、视觉特效、动态图形和音频后期制作融于一身的解决方案&#xff01;它采用美观新颖的界面设计&#xff0c;易学易用&#xff0c;能让新手用户快速上手操作&#xff0c;还能提供专业人士需要的强大性能…

【论文速递】WACV2023 - 循环相似注意力的小样本医学图像分割

【论文速递】WACV2023 - 循环相似注意力的小样本医学图像分割 【论文原文】&#xff1a;Few-shot Medical Image Segmentation with Cycle-resemblance Attention 获取地址&#xff1a;https://arxiv.org/pdf/2212.03967.pdf博主关键词&#xff1a; 小样本学习&#xff0c;语…

SpringCloud系列(九)[docker 篇] - Centos 7 下 Docker 的安装及基本操作指令

本篇文章将详细介绍 Centos 7 下 Docker 的安装以及一些基本操作指令. DockerDocker 的安装步骤Docker 基本操作指令Docker 的安装步骤 步骤一: 确保自己电脑的虚拟机联网并安装了 yum 工具, 如果没有安装 yum, 则执行下面的命令; yum install -y yum-utils \device-mapper-p…

力扣:多数元素(详解)

前言&#xff1a;本期是关于多数元素的详解&#xff0c;内容包括四大模块&#xff1a;题目&#xff0c;代码实现&#xff0c;大致思路&#xff0c;代码解读 今天你c了吗&#xff1f; 题目&#xff1a; 给定一个大小为 n 的数组 nums &#xff0c;返回其中的多数元素。多数元…