MySQL8 新特性——窗口函数用法

news2024/11/28 17:37:41

MySQL8 新特性——窗口函数用法

MySQL 8.0 是 MySQL 数据库管理系统的一个重要版本,引入了许多新特性和改进。以下是 MySQL 8.0 的一些主要新特性:

  1. 事务隔离级别改进: MySQL 8.0 引入了新的事务隔离级别 SERIALIZABLE,提供了最高级别的事务隔离,确保了数据的完整性和一致性。同时,它对其他事务隔离级别的实现也进行了改进,提高了并发性和性能。

  2. Window Functions 支持: MySQL 8.0 引入了窗口函数(Window Functions)的支持,使得在查询中进行复杂的分析和聚合变得更加灵活和高效。窗口函数可以与 OVER 子句一起使用,实现分组、排序、排名等操作。

  3. Common Table Expressions (CTEs) 支持: MySQL 8.0 支持通用表达式(CTEs),允许在查询中使用 WITH 子句来定义临时结果集,简化了复杂查询的编写。

  4. JSON 支持改进: MySQL 8.0 对 JSON 支持进行了改进,包括支持更多的 JSON 函数和操作,以及更高效的 JSON 存储格式,使得在 MySQL 中存储和查询 JSON 数据更加方便。

  5. 新增 Data Dictionary: MySQL 8.0 引入了 Data Dictionary 来替代之前的 .frm 文件,用于存储数据库元数据信息,提高了数据库的可靠性和扩展性。

  6. InnoDB 存储引擎改进: MySQL 8.0 对 InnoDB 存储引擎进行了多项改进,包括支持更大的表空间、在线表重建、数据压缩和加密、性能优化等。

  7. 全局事务标识(GTID)改进: MySQL 8.0 改进了全局事务标识(GTID)的支持,简化了主从复制配置和管理,提高了复制的可靠性。

  8. Persistent Configuration Variables: MySQL 8.0 引入了持久配置变量,允许将配置参数的值持久化到配置文件中,重启后仍然保持设置。

  9. 离线数据迁移: MySQL 8.0 支持通过 ALTER TABLE 命令进行离线数据迁移,不再需要使用 pt-online-schema-change 工具。

  10. 二进制日志改进: MySQL 8.0 对二进制日志进行了改进,包括支持多线程写入、事务重放和文件格式改进,提高了日志的性能和可靠性。

以上只是 MySQL 8.0 的一部分新特性,该版本还有许多其他改进,如更好的性能、安全性和扩展性等。MySQL 8.0 的发布为用户提供了更多的功能和选项,使得 MySQL 数据库成为更强大和可靠的数据库解决方案。

窗口函数

窗口函数的作用类似于在查询中对数据进行分组,不同的是,分组操作会把分组的结果聚会成一条记录,而窗口函数是将结果置于每一条数据记录中。

分类

窗口函数可以根据其功能和用途进行分类。在MySQL中,根据其功能,窗口函数主要可以分为以下几类:

  1. 排名函数(Ranking Functions):

    • ROW_NUMBER(): 返回每行在结果集中的唯一编号。
    • RANK(): 计算并返回排序后的行在结果集中的排名,相同值有相同的排名,跳过相同排名。
    • DENSE_RANK(): 计算并返回排序后的行在结果集中的排名,相同值有相同的排名,不跳过相同排名。
    • NTILE(n): 将结果集划分为n个近似相等大小的桶,并为每行分配一个桶编号。
  2. 聚合函数(Aggregate Functions):

    • SUM(): 对窗口中的数值列进行求和。
    • AVG(): 对窗口中的数值列进行求平均值。
    • MIN(): 返回窗口中数值列的最小值。
    • MAX(): 返回窗口中数值列的最大值。
    • COUNT(): 返回窗口中行的数量。
  3. 累积函数(Aggregate Functions with ORDER BY):

    • SUM() OVER (): 对窗口中的数值列进行累积求和。
    • AVG() OVER (): 对窗口中的数值列进行累积求平均值。
    • MIN() OVER (): 返回窗口中数值列的累积最小值。
    • MAX() OVER (): 返回窗口中数值列的累积最大值。
  4. 分析函数(Analytic Functions):

    • LEAD(): 获取当前行后面指定偏移量的行的值。
    • LAG(): 获取当前行前面指定偏移量的行的值。
    • FIRST_VALUE(): 返回窗口中指定列的第一个值。
    • LAST_VALUE(): 返回窗口中指定列的最后一个值。
    • PERCENT_RANK(): 计算并返回排序后的行在结果集中的百分比排名。(rank - 1) / (rows - 1)
    • CUME_DIST(): 计算并返回排序后的行在结果集中的累积分布百分比。

这些是窗口函数的常见分类,每个类别有不同的用途和计算功能,可以根据具体的数据处理需求选择合适的窗口函数来实现复杂的查询和分析操作。

静态/动态窗口函数

实际上,窗口函数在MySQL中并没有严格的"静态"和"动态"分类。窗口函数通常根据其特性和功能进行分类,如我之前所述的排名函数、聚合函数、累积函数和分析函数等。这些分类基于窗口函数的不同计算方式和用途。

然而,可能你提到的"静态窗口函数"和"动态窗口函数"是指窗口函数在窗口帧(Window Frame)中的范围设置方式。窗口帧定义了在计算窗口函数时,应该包含哪些行。在MySQL中,有两种常见的窗口帧设置方式:

  1. 静态窗口函数(Static Window Functions):在静态窗口函数中,窗口帧的范围是固定的,不随行的位置变化而改变。最常见的静态窗口帧是使用ROWS BETWEEN子句,指定相对于当前行的固定范围来定义窗口。
SELECT
  column1,
  column2,
  SUM(column3) OVER (ORDER BY column1 ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS sum_column3
FROM
  your_table;

在上述例子中,使用ROWS BETWEEN 2 PRECEDING AND CURRENT ROW定义了一个静态窗口帧,窗口包含当前行以及前面两行的数据。

  1. 动态窗口函数(Dynamic Window Functions):在动态窗口函数中,窗口帧的范围随着行的位置而变化。最常见的动态窗口帧是使用RANGE BETWEEN子句,基于值的范围来定义窗口。
SELECT
  column1,
  column2,
  SUM(column3) OVER (ORDER BY column1 RANGE BETWEEN INTERVAL 1 HOUR PRECEDING AND CURRENT ROW) AS sum_column3
FROM
  your_table;

在上述例子中,使用RANGE BETWEEN INTERVAL 1 HOUR PRECEDING AND CURRENT ROW定义了一个动态窗口帧,窗口包含当前行及其前面1小时内的数据,根据时间的变化而自动调整范围。

需要注意的是,动态窗口函数在MySQL中的支持有限,而且使用时需要谨慎,因为它可能涉及对窗口中的所有数据进行排序,对性能有一定的影响。大多数情况下,静态窗口函数已经能够满足大部分需求。

语法结构

在MySQL中,窗口函数的语法结构如下:

<窗口函数> OVER (
  [PARTITION BY partition_expression]
  [ORDER BY sort_expression [ASC | DESC], ...]
  [window_frame]
)

让我们逐个解释每个部分的含义:

  1. <窗口函数>:这是要执行的窗口函数,可以是聚合函数(如SUM()、AVG()、MIN()、MAX()、COUNT()等)、排名函数(如ROW_NUMBER()、RANK()、DENSE_RANK()、NTILE()等)或其他分析函数(如LEAD()、LAG()、FIRST_VALUE()、LAST_VALUE()、PERCENT_RANK()、CUME_DIST()等)。

  2. OVER ():这是定义窗口的关键字,它后面跟着圆括号,用于包含窗口的设置。

  3. PARTITION BY partition_expression:这是可选的子句,用于将结果集分成不同的分区(组)。partition_expression是一个表达式,根据它的值来划分不同的分区。窗口函数将在每个分区内独立计算。

  4. ORDER BY sort_expression [ASC | DESC], ...:这也是可选的子句,用于在每个分区内对数据进行排序。sort_expression是一个表达式,用于指定排序的规则。可以指定多个排序表达式,并可以指定升序(ASC)或降序(DESC)。

  5. window_frame:这是可选的子句,用于指定在每个分区中用于窗口函数的行范围。它决定了哪些行包含在计算中。窗口帧可以基于当前行的相对位置(ROWS [n] PRECEDING或FOLLOWING)或基于列的值(RANGE BETWEEN value1 AND value2)。如果未指定window_frame,则窗口函数默认使用所有分区中的所有行。

请注意,窗口函数的具体语法可能因数据库管理系统的版本而有所不同。以上语法适用于MySQL 8.0及以上版本,其他数据库系统(如SQL Server、PostgreSQL等)的语法可能稍有不同。在使用时请根据具体的数据库版本和语法规则进行相应调整。

部分函数用法介绍

在这里插入图片描述

#准备工作
CREATE TABLE goods
(
    id          INT PRIMARY KEY AUTO_INCREMENT,
    category_id INT,
    category    VARCHAR(15),
    NAME        VARCHAR(30),
    price       DECIMAL(10, 2),
    stock       INT,
    upper_time  DATETIME
);

INSERT INTO goods (category_id, category, NAME, price, stock, upper_time)
VALUES (1, '女装/女士精品', 'Th', 39.90, 1000, '2023-7-23 00:00:00'),
       (1, '女装/女士精品', '连衣裙', 79.98, 2500, '2023-7-23 00:00:00'),
       (1, '女装/女士精品', '卫衣', 89.98, 1500, '2023-7-23 00:00:00'),
       (1, '女装/女士精品', '牛仔裤', 89.98, 3500, '2023-7-23 00:00:00'),
       (1, '女装/女士精品', '百智精', 29.98, 500, '2023-7-23 00:00:00'),
       (1, '女装/女士精品', '呢绒外套', 399.98, 128, '2023-7-23 00:00:00'),
       (2, '户外运动', '自行车', 399.98, 2300, '2023-7-23 00:00:00'),
       (2, '户外运动', '山地自行车', 1399.98, 2500, '2023-7-23 00:00:00'),
       (2, '户外运动', '连山秋', 59.98, 1599, '2023-7-23 00:00:00'),
       (2, '户外运动', '骑行装备', 399.98, 3568, '2023-7-23 00:00:00'),
       (2, '户外运动', '运动外套', 799.98, 500, '2023-7-23 00:00:00'),
       (2, '户外运动', '滑板', 499.9, 1200, '2023-7-23 00:00:00');

ROW_NUMBER()

## ROW_NUMBER()
# 查询每个商品分类下 再按价格降序排序信息
SELECT ROW_NUMBER() OVER (PARTITION BY category_id ORDER BY price DESC) AS row_num, id, category_id, category, NAME, price, stock
FROM goods;

在这里插入图片描述

# 查询每个商品分类下价格最高的3种商品信息
SELECT *
FROM (SELECT ROW_NUMBER() over (PARTITION BY category ORDER BY price DESC) AS row_num, id, category_id, category, NAME, price, stock FROM goods) t
WHERE row_num <= 3;

在这里插入图片描述

RANK()

# 和 ROW_NUMBER() 区别 当price价格一样时,ROW_NUMBER()返回1,2,3;而 RANK() 返回1,2,2,4
# 获取各个类别的价格从高到低排序
SELECT RANK() OVER (PARTITION BY category_id ORDER BY price DESC) AS row_num, id, category_id, category, NAME, price, stock
FROM goods;

在这里插入图片描述

DENSE_RANK()

# 返回的序号不会跳过重复的序号,比如返回1,2,2,3
SELECT DENSE_RANK() OVER (PARTITION BY category_id ORDER BY price DESC) AS row_num, id, category_id, category, NAME, price, stock
FROM goods;

在这里插入图片描述

PERCENT_RANK()

## PERCENT_RANK()
# 计算名称为"女装/女士精品"的类别下的商品的PERCENT_RANK值
SELECT RANK() OVER w         AS r,
       PERCENT_RANK() OVER w AS pr,
       id,
       category_id,
       category,
       NAME,
       price,
       stock
FROM goods
WHERE category_id = 1 WINDOW w AS (PARTITION BY category_id ORDER BY price DESC);
# 写法方式二:
SELECT RANK() OVER (PARTITION BY category_id ORDER BY price DESC)         AS r,
       PERCENT_RANK() OVER (PARTITION BY category_id ORDER BY price DESC) AS pr,
       id,
       category_id,
       category,
       NAME,
       price,
       stock
FROM goods
WHERE category_id = 1;

在这里插入图片描述

CUME_DIST()

# 主要用于查询小于或等于当前价格的比例
SELECT CUME_DIST() OVER (PARTITION BY category_id ORDER BY price DESC) AS row_num, id, category_id, category, NAME, price, stock
FROM goods;

在这里插入图片描述

LAG(expr, n)、LEAD(expr, n)

## LAG(expr, n)
# 返回当前行的前n行的expr的值
# 查询前一个商品与当前商品价格的差值
# 之前遇到过一个求历史修改记录差异可以用这个!!!,当时听负责人的加了parent_id
SELECT id,
       category_id,
       category,
       NAME,
       price,
       price - pre_price AS diff_prive,
       pre_price,
       pre_id
FROM (SELECT id, category_id, category, NAME, price, LAG(price, 1) OVER (ORDER BY price) AS pre_price, LAG(id, 1) OVER ( ORDER BY price) AS pre_id
      FROM goods) t;

## LEAD(expr, n)
# 返回当前行的后n行的expr的值,类似⬆️

在这里插入图片描述

FIRST_VALUE(expr)、LAST_VALUE(expr)

## FIRST_VALUE(expr)
# 返回第一个expr的值
SELECT id, category_id, category, NAME, price, stock, FIRST_VALUE(price) OVER (PARTITION BY category_id ORDER BY price) AS first_price
FROM goods;

## LAST_VALUE(expr)
# 返回最后一个expr的值

在这里插入图片描述

NTH_VALUE(expr, n)

## NTH_VALUE(expr, n)
# 查询排名第2和第3的价格信息
SELECT id,
       category,
       NAME,
       price,
       NTH_VALUE(price, 2) OVER (PARTITION BY category_id ORDER BY price) AS second_price,
       NTH_VALUE(price, 3) OVER (PARTITION BY category_id ORDER BY price) AS third_price
FROM goods;

在这里插入图片描述

NTILE(n)

## NTILE(n) 分为n组
SELECT NTILE(4) OVER (PARTITION BY category_id ORDER BY price DESC) AS row_num, id, category_id, category, NAME, price, stock
FROM goods;

在这里插入图片描述

总结

窗口函数的特点是可以分组,而且可以在分组内排序。另外,窗口函数不会因为分组减少原表中的行数,这对我们在原表数据的基础上进行统计和排序非常有用。

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

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

相关文章

妙记多 Mojidoc PC端(Mac 端+windows端)Beta版本正式上线!

你们呼唤了无数次的妙记多 Mojidoc PC客户端 Beta版本正式上线啦&#xff01; 感谢300位妙友积极参与内测&#xff0c;给予了我们很多非常有效的意见和建议&#xff01;我们会根据用户反馈不断优化和修复相关功能&#xff0c;在此感谢妙友们一直以来的支持&#xff5e; PC端拥…

静态html引入ucharts并直接使用组件标签

由于官方不能直接使用qiun-vue-ucharts在静态html页面使用。 DIY可视化对此类库进行了改进&#xff0c;把它的包独立打包成一个可以依赖的JS。 首先定义一个核心JS&#xff0c;用于打包生成uchart import qiunVueUcharts from qiun/vue-ucharts;const install (app) > {…

el-select实现el-option可编辑

鼠标悬浮出现编辑图标 点击编辑图标对选择项进行修改 核心代码如下&#xff0c;注意el-input不要使用focus&#xff0c;会导致el-select面板收起来&#xff1b;使用click.native.stop即可 <el-select v-model"value" placeholder"选择" style"widt…

酷雷曼无人机技能培训考试圆满举办

2023年7月18日、19日&#xff0c;以“向云端起航&#xff0c;让技术落地”为主题的酷雷曼无人机技能提升培训会在酷雷曼北京运营中心隆重举行&#xff0c;来自全国各地的众多合作商参加了本次培训&#xff0c;通过系统、全面的学习成功取得了专业无人机飞行员执照&#xff0c;为…

基于linux下的高并发服务器开发(第三章)- 3.10 死锁

deadlock.c #include <stdio.h> #include <pthread.h> #include <unistd.h>// 全局变量&#xff0c;所有的线程都共享这一份资源。 int tickets 1000;// 创建一个互斥量 pthread_mutex_t mutex;void * sellticket(void * arg) {// 卖票while(1) {// 加锁pt…

十、正则表达式详解:掌握强大的文本处理工具(二)

文章目录 &#x1f340;多字符匹配&#x1f340;匹配规则的代替&#x1f340;特殊的匹配&#x1f340;特殊的匹配plus&#x1f340;总结 &#x1f340;多字符匹配 星号&#xff08;*&#xff09;&#xff1a;匹配0个或者多个字符 import retext 111-222-333 result re.matc…

Cardboard for Pictures(cf)

Mircea有n张照片&#xff0c;第 i 张照片的是边长为si的正方形&#xff0c;他把每张照片都装在一块正方形的硬纸板上&#xff0c;这样每张照片的四周都有一个w厘米的硬纸板边框。他总共用了 c 立方厘米见方的硬纸板。给定图片大小和值c&#xff0c;求w。&#xff08;请注意&…

Java-API简析_java.net.InetSocketAddress类(基于 Latest JDK)(浅析源码)

【版权声明】未经博主同意&#xff0c;谢绝转载&#xff01;&#xff08;请尊重原创&#xff0c;博主保留追究权&#xff09; https://blog.csdn.net/m0_69908381/article/details/131870760 出自【进步*于辰的博客】 因为我发现目前&#xff0c;我对Java-API的学习意识比较薄弱…

Dubbogo 详解

Dubbogo 详解 简介 dubbo功能很强大的微服务开发框架&#xff0c;支持多种通信协议&#xff0c;并具有流量治理的功能。 dubbo在有了大转变&#xff0c;拥抱了云原生&#xff0c;从哪些方面可以体现呢&#xff1f; 推出了自己的Trip协议修复了服务发现的级别&#xff0c;之…

Bug竞技场【已经修复】

目录 1.基础知识 2.最佳组合 2.1 铁男-螳螂 2.2 弟弟组合 海克斯抽卡bug 1.基础知识 背景&#xff1a;美测服-美服-马服-可以有效地减少bug率 复盘是为了更好的战斗&#xff01; 提前观看一些视频资料也是如此。 通过看直播博主的经验&#xff0c;可以让你关注到本来对战的…

利用Canvas根据经纬度绘制轨迹(一)

根据经纬度坐标绘制轨迹图形 一段时间没更新了&#xff0c;主人最近有点懒~ 前段时间有个需求&#xff0c;在uniapp App端实现轨迹绘制&#xff0c;于是先用html实现看看效果~ 效果图 html <canvasid"canvasId"width"300"height"300"style&…

DOS命令(windows)

DOS命令&#xff08;windows&#xff09; 目录 1. 打开命令提示符。2. 切换至根。3. 当前路径。4. 切换至上级路径。5. 查看当前目录。6. 查看文件内容。7. 删除文件。8. 进入长文件夹名时缩写。9. 复制文件。10. 移动文件。 1. 打开命令提示符。 命令&#xff1a;winR 输入&a…

【Go】Go 语言开发工具GoLand 使用(二十二)

往期回顾&#xff1a; Go 语言教程–介绍&#xff08;一&#xff09;Go 语言教程–语言结构&#xff08;二&#xff09;Go 语言教程–语言结构&#xff08;三&#xff09;Go 语言教程–数据类型&#xff08;四&#xff09;Go 语言教程–语言变量&#xff08;五&#xff09;Go …

STM32外设系列—TB6612FNG

本文涉及到定时器和串口的知识&#xff0c;详细内容可见博主STM32速成笔记专栏。 文章目录 一、TB6612简介二、TB6612使用方法2.1 TB6612引脚连接2.2 控制逻辑2.3 电机调速 三、实战项目3.1 项目简介3.2 初始化GPIO3.3 PWM初始化3.3 电机控制程序3.4 串口接收处理函数 一、TB66…

PHP反序列化漏洞之魔术方法

一、魔术方法 PHP魔术方法&#xff08;Magic Methods&#xff09;是一组特殊的方法&#xff0c;它们在特定的情况下会被自动调用&#xff0c;用于实现对象的特殊行为或提供额外功能。这些方法的名称都以双下划线开头和结尾&#xff0c;例如: __construct()、__toString()等。 …

java项目之网络视频播放器(ssm+mysql+jsp)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的网络视频播放器。技术交流和部署相关看文章末尾&#xff01; 开发环境&#xff1a; 后端&#xff1a; 开发语言&#xff1a;Java 框架&a…

Arduino RP2040 两个CDC虚拟串口通讯

Arduino RP2040 两个CDC虚拟串口通讯 &#x1f3ac;通讯效果演示&#xff1a; &#x1f33f;基于Earle F. Philhower的固件开发平台&#xff1a; https://github.com/earlephilhower/arduino-pico&#x1f516;USB配置参考&#xff1a;https://arduino-pico.readthedocs.io/en/…

【算法基础:数学知识】4.1 质数

文章目录 质数例题列表866. 试除法判定质数&#xff08;质数的判定&#xff09;867. 分解质因数&#xff08;&#xff09;868. 筛质数埃氏筛欧氏筛 / 线性筛 相关链接 质数 定义&#xff1a;质数是指在大于1的自然数中&#xff0c;除了1和它本身以外不再有其他因数的自然数。 …

安装Electron时报错command sh -c node install.js

在安装Electron报如下错误 在指令后面添加 --ignore-scripts&#xff0c;意思是npm 将不会运行在package.json中指定的scripts npm install --save -dev electron --ignore-scripts

Linux系统安装部署MySQL完整教程(图文详解)

前言&#xff1a;最近网上翻阅了大量关于Linux安装部署MySQL的教程&#xff0c;在自己部署的时候总是存在一些小问题&#xff0c;例如&#xff1a;版本冲突&#xff0c;配置失败和启动失败等等&#xff0c;功夫不负有心人&#xff0c;最后还是安装部署成功了&#xff0c;所以本…