SQL 窗口函数

窗口函数(Window Function)是SQL中用于在查询结果的某个"窗口"或"子集"上执行计算的功能。它们通常与OVER()子句一起使用,允许在不改变行数的情况下对数据进行聚合、排序或分析。窗口函数不会像GROUP BY那样将多行合并为一行,而是保留原始行的同时进行计算。

常见的窗口函数包括以下几类:

1. 聚合窗口函数

在窗口内执行聚合操作,例如:

  • SUM():计算窗口内某列的总和。

  • AVG():计算窗口内某列的平均值。

  • MIN():计算窗口内某列的最小值。

  • MAX():计算窗口内某列的最大值。

  • COUNT():计算窗口内的行数。

sql 复制代码
SELECT 
    employee_id, 
    salary, 
    SUM(salary) OVER (PARTITION BY department_id) AS department_total_salary
FROM employees;

这会计算每个部门的工资总和,同时保留每个员工的原始行


2. 排序窗口函数

根据窗口内的排序规则为每行分配一个值,例如:

  • ROW_NUMBER():为窗口内的每一行分配一个唯一的行号。

  • RANK():为窗口内的每一行分配排名,相同值会有相同的排名,后续排名会跳过。

  • DENSE_RANK():与RANK()类似,但不会跳过后续排名。

  • NTILE(n):将窗口内的行分成n个桶,并为每行分配桶号。

sql 复制代码
SELECT 
    employee_id, 
    salary, 
    RANK() OVER (ORDER BY salary DESC) AS salary_rank
FROM employees;

这会根据工资从高到低为员工分配排名


3. 分析窗口函数

用于计算窗口内的相对值或变化,例如:

  • LAG():获取窗口中当前行之前的某一行的值。

  • LEAD():获取窗口中当前行之后的某一行的值。

  • FIRST_VALUE():获取窗口内第一行的值。

  • LAST_VALUE():获取窗口内最后一行的值。

sql 复制代码
SELECT 
    employee_id, 
    salary, 
    LAG(salary, 1) OVER (ORDER BY salary) AS previous_salary
FROM employees;

这会获取当前行前一行(按工资排序)的工资值


4. 窗口定义

窗口函数的核心是OVER()子句,它定义了窗口的范围。常见的窗口定义方式包括:

  • PARTITION BY:将数据分组,窗口函数在每个分组内独立计算。

  • ORDER BY:指定窗口内的排序规则。

  • ROWSRANGE:定义窗口的物理或逻辑范围(例如前N行、后N行、当前行到末尾等)

sql 复制代码
SELECT 
    employee_id, 
    salary, 
    AVG(salary) OVER (PARTITION BY department_id ORDER BY hire_date ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS moving_avg
FROM employees;

这会计算每个部门中,按入职日期排序后,当前行及其前后一行的工资平均值


应用场景

窗口函数常用于以下场景:

  • 计算累计值(如累计销售额)。

  • 计算移动平均值(如过去3个月的平均值)。

  • 排名和分组分析(如部门内工资排名)。

  • 比较当前行与前一行或后一行的值(如环比分析)

sql 复制代码
SELECT 
    employee_id, 
    department_id, 
    salary, 
    SUM(salary) OVER (PARTITION BY department_id) AS dept_total,
    AVG(salary) OVER (PARTITION BY department_id) AS dept_avg,
    RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS dept_rank,
    LAG(salary, 1) OVER (ORDER BY hire_date) AS prev_salary
FROM employees;

这个查询会返回每个员工的工资、部门总工资、部门平均工资、部门内工资排名以及前一个员工的工资

窗口函数是SQL中非常强大的工具,能够在不改变数据粒度的情况下进行复杂的分析和计算

相关推荐
小Tomkk17 分钟前
数据库 变更和版本控制管理工具 --Bytebase 安装部署(linux 安装篇)
linux·运维·数据库·ci/cd·bytebase
qq_124987075342 分钟前
基于JavaWeb的大学生房屋租赁系统(源码+论文+部署+安装)
java·数据库·人工智能·spring boot·计算机视觉·毕业设计·计算机毕业设计
倒流时光三十年1 小时前
SpringBoot 数据库同步 Elasticsearch 性能优化
数据库·spring boot·elasticsearch
码农小卡拉2 小时前
深入解析Spring Boot文件加载顺序与加载方式
java·数据库·spring boot
怣502 小时前
MySQL多表连接:全外连接、交叉连接与结果集合并详解
数据库·sql
wjhx2 小时前
QT中对蓝牙权限的申请,整理一下
java·数据库·qt
冰暮流星2 小时前
javascript之二重循环练习
开发语言·javascript·数据库
万岳科技系统开发3 小时前
食堂采购系统源码库存扣减算法与并发控制实现详解
java·前端·数据库·算法
冉冰学姐3 小时前
SSM智慧社区管理系统jby69(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·管理系统·智慧社区·ssm 框架
杨超越luckly3 小时前
HTML应用指南:利用GET请求获取中国500强企业名单,揭秘企业增长、分化与转型的新常态
前端·数据库·html·可视化·中国500强