Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > Mysql开窗函数

一文深入解析Mysql的开窗函数(易懂版)

作者:不辉放弃

在MySQL中窗口函数是一类非常强大的函数,它们允许你在不改变表数据的情况下,对数据进行复杂的分析和计算,这篇文章主要介绍了Mysql开窗函数的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

前言

SQL 开窗函数(Window Function)是一种强大的分析工具,它能在保留原有数据行的基础上,对 "窗口"(指定范围的行集合)进行聚合、排名或分析计算,解决了传统GROUP BY聚合会合并行的局限性。

一、开窗函数的核心特点

二、基本语法结构

开窗函数的通用语法:

函数名(参数) OVER (
  [PARTITION BY 分区列1, 分区列2...]  -- 可选:按列分组,每组独立计算
  [ORDER BY 排序列1 [ASC|DESC], ...]  -- 可选:分区内的排序方式
  [ROWS | RANGE 窗口范围]  -- 可选:定义窗口的具体行范围(行级窗口)
)

三、OVER()子句详解

1. PARTITION BY:分区(分组)

2. ORDER BY:分区内排序

3. ROWS | RANGE:窗口范围(行级窗口)

四、常用开窗函数分类及示例

以下示例基于员工表employee,结构如下:

idnamedepartmentsalaryhire_date
1张三技术部80002020-01-15
2李四技术部90002019-03-20
3王五技术部90002018-05-10
4赵六市场部70002021-02-05
5钱七市场部85002020-08-18

1. 排名函数(用于生成排名)

(1)ROW_NUMBER():生成唯一序号

SELECT 
  name, 
  department, 
  salary,
  ROW_NUMBER() OVER (
    PARTITION BY department 
    ORDER BY salary DESC, hire_date ASC
  ) AS row_num
FROM employee;

(2)RANK():带跳号的排名

SELECT 
  name, 
  department, 
  salary,
  RANK() OVER (
    PARTITION BY department 
    ORDER BY salary DESC
  ) AS rank_num
FROM employee;

(3)DENSE_RANK():无跳号的排名

SELECT 
  name, 
  department, 
  salary,
  DENSE_RANK() OVER (
    PARTITION BY department 
    ORDER BY salary DESC
  ) AS dense_rank_num
FROM employee;

2. 聚合开窗函数(聚合函数 +OVER())

SUM()AVG()COUNT()等聚合函数与OVER()结合,为每行计算所在窗口的聚合结果。

(1)全分区聚合(无ORDER BY和范围)

SELECT 
  name, 
  department, 
  salary,
  AVG(salary) OVER (PARTITION BY department) AS dept_avg_salary
FROM employee;

(2)累计聚合(带ORDER BY和范围)

SELECT 
  name, 
  department, 
  hire_date,
  salary,
  SUM(salary) OVER (
    PARTITION BY department 
    ORDER BY hire_date ASC
    ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW  -- 从第一行到当前行
  ) AS cumulative_salary
FROM employee;

3. 分析函数(获取前后行数据)

(1)LAG(列名, n):获取当前行的前 n 行数据

SELECT 
  name, 
  department, 
  hire_date,
  salary,
  LAG(salary, 1) OVER (
    PARTITION BY department 
    ORDER BY hire_date ASC
  ) AS prev_emp_salary
FROM employee;

(2)LEAD(列名, n):获取当前行的后 n 行数据

SELECT 
  name, 
  department, 
  hire_date,
  salary,
  LEAD(salary, 1) OVER (
    PARTITION BY department 
    ORDER BY hire_date ASC
  ) AS next_emp_salary
FROM employee;

五、开窗函数与GROUP BY的区别

特性GROUP BY聚合开窗函数
行处理合并分组后的行(一行 / 组)保留所有原始行
计算范围整个分组可自定义窗口范围(分区、行范围)
结果列仅聚合结果 + 分组列原始列 + 开窗计算结果

六、注意事项

通过上述讲解,可掌握开窗函数的核心语法和应用场景。实际使用时,需根据业务需求灵活组合PARTITION BYORDER BY和窗口范围,实现复杂的数据分析。

到此这篇关于Mysql开窗函数的文章就介绍到这了,更多相关Mysql开窗函数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文