可以再查询每一行里面,添加新字段,这个字段通过窗口函数,可以在查询时,根据某个字段进行聚合操作运算后再单独赋值给这一行在这个聚合中获得的值!!!!
窗口函数(Window Function)是 SQL 中非常强大的功能,用于在不改变结果集行数的前提下,对每行数据进行基于"窗口"(一组相关行)的计算。常用于排名、累计求和、移动平均、前后行比较等场景。
✅ 经典应用场景
场景 窗口函数
- 分组 Top N ROW_NUMBER() OVER (PARTITION BY ... ORDER BY ...)
- 累计求和/占比 SUM(x) OVER (ORDER BY ...)
- 同比/环比 LAG(amount) OVER (ORDER BY date)
- 移动平均 AVG(x) OVER (ORDER BY ... ROWS ...)
- 去重取最新 ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY create_time DESC)
基本语法
bash
function_name(expression) OVER (
[PARTITION BY partition_expression, ...]
[ORDER BY sort_expression [ASC|DESC], ...]
[frame_clause]
)
- function_name:窗口函数名(如 ROW_NUMBER(), SUM(), LAG() 等)
- PARTITION BY:将数据分组(类似 GROUP BY,但不聚合行)
- ORDER BY:定义窗口内行的顺序
- frame_clause:定义窗口范围(如 ROWS BETWEEN ...)
二、常用窗口函数分类
1️⃣ 排名函数
函数 说明 - ROW_NUMBER() 连续唯一排名(1,2,3,...)
- RANK() 跳跃排名(相同值并列,下一名跳过,如 1,1,3)
- DENSE_RANK() 密集排名(相同值并列,下一名连续,如 1,1,2)
✅ 示例:按部门对员工薪资排名
sql
SELECT
name,
dept,
salary,
ROW_NUMBER() OVER (PARTITION BY dept ORDER BY salary DESC) AS rn,
RANK() OVER (PARTITION BY dept ORDER BY salary DESC) AS rnk,
DENSE_RANK() OVER (PARTITION BY dept ORDER BY salary DESC) AS drnk
FROM employees;
2️⃣ 聚合函数(作为窗口函数)
普通聚合函数(SUM, AVG, COUNT, MAX, MIN)加上 OVER() 就变成窗口聚合。
✅ 示例:累计销售额
sql
SELECT
order_date,
amount,
SUM(amount) OVER (ORDER BY order_date) AS running_total
FROM sales;
✅ 示例:各部门平均工资(每行显示该部门平均值)
sql
SELECT
name,
dept,
salary,
AVG(salary) OVER (PARTITION BY dept) AS avg_dept_salary
FROM employees;
3️⃣ 偏移函数(前后行访问)
函数 说明
- LAG(col, n) 获取当前行前第 n 行的 col 值
- LEAD(col, n) 获取当前行后第 n 行的 col 值
- FIRST_VALUE(col) 窗口第一行的值
- LAST_VALUE(col) 窗口最后一行的值
✅ 示例:计算每日销售额与前一天的差值
sql
SELECT
order_date,
amount,
LAG(amount, 1) OVER (ORDER BY order_date) AS prev_amount,
amount - LAG(amount, 1) OVER (ORDER BY order_date) AS diff
FROM sales;