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

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

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

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

相关文章:

  • input组件使用type=“number“的时候,光标自动跳到首位
  • 【Tools】VMware Workstation 17.6 Pro安装教程
  • 在 CentOS 7.9 上部署 node_exporter 并接入 Prometheus + Grafana 实现主机监控
  • PyMOL命令行和脚本
  • 精益数据分析(70/126):MVP迭代中的数据驱动决策与功能取舍
  • AI神经网络降噪 vs 传统单/双麦克风降噪的核心优势对比
  • 公网ip是固定的吗?动态ip如何做端口映射?内网ip怎么让外网远程访问?
  • 组态王通过开疆智能profinet转ModbusTCP网关连接西门子PLC配置案例
  • 学习BI---QuickBI介绍
  • ngx_http_scgi_module 技术指南
  • 问题 | 代码审查:函数是否包含返回语句
  • 调研函模板可参考,以无人机职业技能调研为例
  • 开源表单设计器FcDesigner配置多语言教程
  • 2024年ASOC SCI2区TOP,多机制群优化算法+多风场输电线路巡检中多无人机任务分配与路径规划,深度解析+性能实测
  • Easy PLC和IT7000触摸屏的无实物仿真调试
  • Rust 学习笔记:关于错误处理的练习题
  • JavaScript 中的五种继承方式进行深入对比
  • 【T2I】LoCo: Locally Constrained Training-Free Layout-to-Image Synthesis
  • Docker 运维管理
  • ipynb文件的一键访问(顺带启动jupyter)实现程序演示
  • 一日双赛“莎头组合”赢得强势,但国乒已开始品尝输球滋味
  • 以色列媒体:以总理称将接管整个加沙
  • 国家统计局:消费对我国经济增长的拉动有望持续增长
  • 自媒体假扮官方蹭反间谍热度攫取利益,国安机关提醒
  • 持续降雨存在落石风险,贵州黄果树景区水帘洞将封闭至6月初
  • 香港特区政府强烈谴责美参议员恐吓国安人员