MySQL 8.0:窗口函数
一、基础知识
-
定义
窗口函数(Window Function)对查询结果集的子集(“窗口”)进行计算,保留原始行而非聚合为单行,适合复杂分析(如排名、累积和)。
基本语法:函数名() OVER ([PARTITION BY 列] -- 按列分组,类似GROUP BY但保留所有行[ORDER BY 列] -- 定义窗口内排序[ROWS/RANGE 范围] -- 指定计算范围 )
-
核心组件
PARTITION BY
:分区列,窗口计算独立于每个分区(如按部门分组)。ORDER BY
:分区内排序,影响排名、累积计算逻辑。- 窗口帧(Frame):
ROWS BETWEEN n PRECEDING AND m FOLLOWING
:指定当前行前后包含的行数。RANGE BETWEEN INTERVAL '1' DAY PRECEDING AND CURRENT ROW
:按值范围定义(如时间间隔)。
二、窗口函数类型
1. 排名函数
函数 | 描述 | 示例场景 |
---|---|---|
ROW_NUMBER() | 唯一连续序号(同值不同号) | 按入职日期排序员工 |
RANK() | 允许并列且后续排名跳跃(如1,1,3) | 销售额排名(同额同排名,后续跳号) |
DENSE_RANK() | 并列排名连续(如1,1,2) | 工资排名(同薪不跳号) |
NTILE(n) | 数据均分n组并分配组号 | 按工资四分位分组 |
2. 分析函数
LAG(列, 偏移量)
/LEAD(列, 偏移量)
:
获取当前行前/后指定偏移量的值(如对比上月销售额):SELECT sale_date, amount, LAG(amount, 1) OVER (ORDER BY sale_date) AS prev_amount FROM sales; -- 获取前一条记录
FIRST_VALUE()
/LAST_VALUE()
:
返回窗口首行/末行的值(如部门最高工资)。
3. 聚合函数(窗口化)
- 累积计算:
SUM(sales) OVER (PARTITION BY product_id ORDER BY date) -- 按产品累计销售额
- 移动平均:
AVG(amount) OVER (ORDER BY date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) -- 近3天移动平均
三、性能优化
- 索引策略:
- 为
PARTITION BY
和ORDER BY
涉及的列创建索引。
- 为