当前位置: 首页 > web >正文

MYSQL8.0常用窗口函数

MYSQL8.0常用窗口函数

一、窗口函数的基本概念

窗口函数,顾名思义,就是在查询结果集中定义一个“窗口”,在这个窗口内进行数据的计算和分析。与普通聚合函数不同,普通聚合函数会将结果集分组并返回每组的单一汇总值,而窗口函数可以在每个行上返回基于窗口内数据的计算结果,并且不会改变结果集的行数。例如,在计算每个员工的工资在部门内的排名时,窗口函数可以在不影响原有员工信息行的基础上,为每行数据添加一个排名列。

窗口函数的语法结构如下:

<窗口函数> OVER ([PARTITION BY 列名]  -- 分组字段[ORDER BY 列名]       -- 排序字段[ROWS/RANGE 窗口范围] -- 可选,定义窗口大小
)

其中,<窗口函数>可以是各种函数,如排序函数、聚合函数、偏移函数等;PARTITION BY用于指定分组条件,类似于GROUP BY,但不会将结果集合并;ORDER BY用于指定窗口内数据的排序顺序;ROWS/RANGE用于定义窗口的范围,可选参数。

二、常见窗口函数及示例

(一)排序函数

排序函数包括ROW_NUMBER()RANK()DENSE_RANK()等,主要用于对窗口内的数据进行排名。

  • ROW_NUMBER():为分组内的行生成唯一连续序号(重复值不影响排名)。常用于分页查询、取每组前N条数据。
SELECT id, dept, salary,ROW_NUMBER() OVER (PARTITION BY dept ORDER BY salary DESC) AS rn  
FROM employees;
  • RANK():分组内重复值排名相同,后续排名跳过重复数(如并列第1名后直接第3名)。适用于获取不考虑重复值的排名场景,如考试排名。
SELECT id, dept, salary,RANK() OVER (PARTITION BY dept ORDER BY salary DESC) AS rnk  
FROM employees;
  • DENSE_RANK():分组内重复值排名相同,后续排名不跳过(如并列第1名后为第2名)。适用于需要紧凑排名的场景,如成绩排名。
SELECT id, dept, salary,DENSE_RANK() OVER (PARTITION BY dept ORDER BY salary DESC) AS drnk  
FROM employees;

(二)聚合函数

聚合函数如SUM()AVG()MAX()MIN()等,可在窗口内进行聚合计算。

  • 计算部门内薪资累计和
SELECT id, dept, salary,SUM(salary) OVER (PARTITION BY dept ORDER BY join_date) AS dept_total  
FROM employees;
  • 计算近3个月的平均薪资(按时间窗口)
SELECT join_date, salary,AVG(salary) OVER (ORDER BY join_date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS moving_avg  
FROM employees;

(三)偏移函数

偏移函数包括LAG()LEAD(),用于获取当前行之前或之后某一行的值。

  • LAG():获取当前行之前第N行的数据,常用于对比前后行数据,如计算同比、环比数据。
SELECT id, dept, salary,LAG(salary, 1) OVER (PARTITION BY dept ORDER BY join_date) AS prev_salary  
FROM employees;
  • LEAD():获取当前行之后第N行的数据,用于对比当前行与后续行数据。
SELECT id, dept, salary,LEAD(salary, 1) OVER (PARTITION BY dept ORDER BY join_date) AS next_salary  
FROM employees;

三、窗口函数的应用场景

(一)排名与分页

在查询数据库时,经常需要对结果进行排名,以便实现分页或获取特定排名的记录。例如,在学生成绩表中,查询每个班级成绩排名前5的学生,就可以使用RANK()函数结合WHERE子句来实现。

(二)分组统计与分析

在分组的基础上进行更复杂的统计分析。例如,在销售数据表中,按月份和地区统计销售额,并计算每个地区在每个月的销售额占该月总销售额的比例,可使用窗口函数结合GROUP BY子句来实现。

(三)数据对比与趋势分析

通过偏移函数可以方便地进行数据对比和趋势分析。例如,在股票交易数据表中,查询每天的股票价格与前一天价格的差值,以分析股票价格的走势,可使用LAG()函数获取前一天的价格,然后与当前天的价格进行计算。

(四)数据填充与补全

在某些情况下,数据可能存在缺失或不完整的情况,窗口函数可以用于填充或补全数据。例如,在一个包含日期和销售额的表中,如果某些日期没有销售额记录,可以使用窗口函数从前一个有记录的日期获取销售额进行填充。

四、窗口函数的性能优化与注意事项

(一)性能优化

  1. 合理使用索引:避免在大表中无索引的列上使用窗口函数,因为窗口函数的计算通常依赖于排序和分组操作,索引可以大大提高这些操作的效率。
  2. 减少窗口范围:尽量缩小窗口的范围,避免使用过大的窗口,因为窗口越大,计算量就越大。如果只需要获取前几行或后几行的数据,明确指定窗口范围,而不是使用默认的全窗口。
  3. 避免重复计算:如果在多个窗口函数中使用了相同的排序和分组条件,可以考虑将这些条件提取到公共部分,避免重复计算。

(二)注意事项

  1. 语法结构:确保正确使用窗口函数的语法结构,特别是PARTITION BYORDER BY和窗口范围的定义,否则可能会导致查询结果不符合预期。
  2. 兼容性:不同的数据库对窗口函数的支持程度和语法略有差异。例如,MySQL 8.0+才支持窗口函数,低版本需用变量模拟;Oracle和SQL Server对窗口函数的支持较为全面,但在一些细节上也有所不同。在使用窗口函数时,要注意数据库的版本和特性。
  3. 数据量影响:对于大数据量的查询,窗口函数的性能可能会受到影响。在这种情况下,可以考虑先对数据进行预处理,如使用临时表或分区表,减少窗口函数的计算量。

五、总结

SQL窗口函数是一种强大而灵活的数据处理工具,它能够帮助我们在复杂的数据查询和分析中,轻松实现各种高级功能。通过本文的介绍,相信大家对窗口函数的基本概念、常见函数、应用场景以及性能优化等方面有了更深入的了解。在实际工作中,希望大家能够熟练运用窗口函数,提高数据处理的效率和质量,让数据为我们创造更大的价值。

如果你在使用窗口函数的过程中遇到任何问题,或者有更多的使用技巧和经验分享,欢迎在评论区留言交流!

上述博客涵盖了窗口函数多方面内容,能帮助读者系统认识和运用它。若你觉得某些部分需补充,或想调整风格,欢迎随时告知。

http://www.xdnf.cn/news/7401.html

相关文章:

  • Qt Widgets模块功能详细说明,基本控件:QCheckBox(三)
  • winrar 工具测试 下载 与安装
  • 计算机网络 第三章:运输层(一)
  • mcp 学习第二篇
  • Python在自动驾驶数据清洗中的应用
  • Java后端面试八股文大全(2025最新版)
  • 5月19日复盘-YOLOV4
  • 采用CDN技术时域名解析流程
  • Java-List集合类全面解析
  • DAY 30 模块和库的导入
  • 扫描网络内所有设备的IP地址
  • 专题讨论3:基于图的基本原理实现走迷宫问题
  • (二十二)Java File类与IO流全面解析
  • 第 1 章:数字 I/O 与串口通信(GPIO UART)
  • LeetCode 1306. 跳跃游戏 III(中等)
  • 4.【Linux】Linux工具(2)
  • 小白的进阶之路-人工智能从初步到精通pytorch的基本流程详解-1
  • 树莓派系列教程第八弹:结合 ESP32-CAM 实现远程摄像头监控
  • 14款项目管理工具点评:PingCode、TAPD等哪款更好?
  • Django框架的前端部分使用Ajax请求一
  • bisheng系列(二)- 本地部署(前后端)
  • SpringBoot 中文转拼音 Pinyin4j库 拼音转换 单据管理 客户管理
  • 电脑A和电脑B都无法ping通电脑C网络,电脑C可以ping通电脑A和B,使用新系统测试正常,排除硬件问题。
  • 【漫话机器学习系列】268. K 折交叉验证(K-Fold Cross-Validation)
  • CAD看图王三维功能升级能解决哪些问题?
  • vulfocus漏洞学习——redis 未授权访问 (CNVD-2015-07557)
  • CSS提高性能的方法有哪些
  • @RequestParam 和 @RequestBody、HttpServletrequest 与HttpServletResponse
  • 解析:新能源汽车芯片主要玩家及技术发展
  • 从秒开到丝滑体验!WebAssembly助力ZKmall商城重构 B2B2C 商城性能基线