sql窗口函数

mysql窗口函数:告别繁琐子查询

在处理排名统计、分组内对比、累计计算这类需求时,你是不是还在写多层子查询、反复关联表?mysql窗口函数就是为解决这类问题而生的高效工具------它能在不聚合数据的前提下,对指定数据集(窗口)内的行做计算,让代码更简洁、性能更优。

窗口函数的核心语法:

<函数名>([expr]) over(

partition by \<列名\>

order by \<列名\> \[asc\|desc\]

rows\|range \<窗口范围\>

)

  • partition by:可选,按指定列分组,每组是一个独立窗口,不分组则整个结果集为一个窗口。

  • order by:可选,定义窗口内数据的排序规则,决定排名、累计等计算的顺序。

  • rows|range:可选,限定窗口内的行范围,比如"当前行的前2行到后1行"。

mysql窗口函数主要分三类,日常开发够用了:

  1. 排名函数: rank() 、 dense_rank() 、 row_number()

三者的核心区别在于处理并列排名的方式:

  • row_number() :不管是否并列,都生成连续序号(1,2,3,4)。

  • rank() :并列会跳过后续序号(1,2,2,4)。

  • dense_rank() :并列不跳过序号(1,2,2,3)。

举个例子,统计每个部门员工的薪资排名:

select

dept, name, salary,

row_number() over(partition by dept order by salary desc) as rn,

rank() over(partition by dept order by salary desc) as rk,

dense_rank() over(partition by dept order by salary desc) as dr

from emp;

  1. 聚合窗口函数: sum() 、 avg() 、 max() 、 min()

和普通聚合函数的区别是,它不会将多行合并为一行,而是保留每行数据,同时计算窗口内的聚合结果。

比如计算每个员工的薪资,以及其所在部门的平均薪资:

select

dept, name, salary,

avg(salary) over(partition by dept) as dept_avg_sal

from emp;

  1. 取值函数: lag() 、 lead() 、 first_value() 、 last_value()

用于获取窗口内指定位置的行数据,解决"和上一条/下一条数据对比"的需求。

  • lag(expr, n) :获取当前行的前n行的expr值。

  • lead(expr, n) :获取当前行的后n行的expr值。

比如查看每个员工的薪资,以及上一位员工的薪资:

select

name, salary,

lag(salary, 1) over(order by salary) as prev_sal

from emp;

最后说个关键:窗口函数和 group by 的区别。 group by 是聚合分组,每组只返回一行结果;窗口函数是开窗计算,会保留所有行,同时附加计算结果。

窗口函数: 用++更少的代码、更高的效率,搞定那些之前需要绕弯子的统计需求++

相关推荐
爱学习的小邓同学39 分钟前
MySQL --- MySQL数据类型
数据库·mysql
weixin_5806140041 分钟前
MySQL存储过程中如何防止SQL注入_使用参数化查询规范
jvm·数据库·python
2401_8371638942 分钟前
PHP源码开发用台式机还是笔记本更合适_硬件选型对比【方法】
jvm·数据库·python
baidu_340998821 小时前
mysql修改列名会导致程序报错吗_Change Column语法与兼容性
jvm·数据库·python
只说证事1 小时前
会计岗位向管理会计升级,最该补哪些数据分析技能
数据库·数据挖掘·数据分析
a9511416422 小时前
如何加固SQL集群防注入_实施网络层访问控制策略
jvm·数据库·python
2401_835956812 小时前
mysql处理大量更新场景_InnoDB MVCC与MyISAM对比
jvm·数据库·python
m0_748920362 小时前
Oracle默认端口被占用如何连接_修改端口号操作教程
jvm·数据库·python
qq_342295822 小时前
Redis怎样按照距离远近排序展示_通过GEORADIUS的ASC参数进行Geo排序
jvm·数据库·python
2201_761040592 小时前
C#比较两个二进制文件的差异 C#如何实现一个二进制diff工具
jvm·数据库·python