当前位置: 首页 > news >正文

MySQL基础之开窗函数

1. 聚合函数和开窗函数的区别

普通聚合函数(如 SUM(), AVG())是纵向聚合:一组数据聚合成一行然后拿到结果;

开窗函数是SQL中的一种横向分析函数,它不改变行数,而是为每一行计算一个基于该行所在分区中其他行的数据结果

例如:“统计每位员工的工资在其所在部门中的排名”。关键词就是“每”,要求每一行数据都要展示,而且是基于其所在部门的排名。

也就是说:

  • 每位员工都要保留在结果中(不能像普通聚合那样合并成一行);
  • 排名是相对于同一部门的其他员工
  • 需要考虑排序(工资越高,排名越靠前);

2. 开窗函数基本组成

函数名(字段参数) OVER ([PARTITION BY 分组字段] # 分区子句,开窗函数将在不同的分区内分别执行[ORDER BY 排序字段] # 排序子句[ROWS BETWEEN start AND end] # 窗口子句,通常用来作为滑动窗口使用
)

对于上面的窗口子句:

  • start的值一般为 1.unbounded preceding,边界是分区中的第一行 2.expr preceding,边界是当前行向上数expr
  • end的值一般为 1. unbounded following,边界是分区中最后一行 2.expr following,边界是当前行向下数expr
  • startend也可以是current row,边界是当前行
  • 默认为ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW

比如:

# 窗口范围是分区中的第一行到当前行
rows unbounded preceding 
# 窗口范围是当前行、当前行的前一行、当前行的后一行,一共三行记录。
rows between 1 preceding and 1 following

边界图如果所示:
在这里插入图片描述

3. 聚合开窗函数

基础数据:
![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/ef57a5b9147440d4adfd136e736d0208.png

需求:统计每位员工从入职到现在,所在部门中总共发了多少钱工资。

SELECT *, 
sum(salary) over(PARTITION by part,username ORDER BY hire_date rows BETWEEN unbounded preceding and current row) as 'total_salary'
from employees

结果如下:
在这里插入图片描述

4. 排名开窗函数

统计每位员工在自己部门中的工资排名

4.1 RANK

特点:1. 相同值的行有相同排名 2. 跳过排名空行(看下面排名从1跳到了3)

SELECT *, RANK() over(PARTITION by part ORDER BY salary desc) as 'salary_rank'
from employees

在这里插入图片描述

4.2 DENSE_RANK

特点:1. 相同值的行有相同的排名 2. 不跳过排名空位(看下面排名1后面是2)

SELECT *, DENSE_RANK() over(PARTITION by part ORDER BY salary desc) as 'salary_rank'
from employees

在这里插入图片描述

4.3 ROW_NUMBER

特点:按原表数据的顺序,为每一行设置一个递增的数字

SELECT *, ROW_NUMBER() over(PARTITION by part ORDER BY salary desc) as 'salary_rank'
from employees

在这里插入图片描述

5. 取值开窗函数

5.1 FIRST_VALUE

需求:查看每位员工所在部门中工资最高的人的工资是多少(即第一名的工资)

SELECT *, FIRST_VALUE(salary) over(PARTITION by part ORDER BY salary desc ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as 'top_salary'
from employees

在这里插入图片描述

5.2 LAST_VALUE

需求:查看每位员工所在部门中工资低的人的工资是多少(即最后第一名的工资)

SELECT *, LAST_VALUE(salary) over(PARTITION by part ORDER BY salary desc ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as 'last_salary'
from employees

在这里插入图片描述

5.3 NTH_VALUE

需求:查看每位员工所在部门中工资排名第二的人的工资是多少

SELECT *, NTH_VALUE(salary, 2) over(PARTITION by part ORDER BY salary desc ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as 'nth_salary'
from employees

在这里插入图片描述

5.4 LAG

需求:查看每位员工所在部门中工资与上一个人的差值

SELECT *, salary - IFNULL(LAG(salary, 1) OVER (PARTITION BY part ORDER BY salary ASC), salary) AS diff_salary
FROM employees

在这里插入图片描述

5.5 LEAD

需求:判断每个员工工资是否高于下一位

SELECT *,CASEWHEN salary > LEAD(salary) OVER (PARTITION BY part) THEN '高于下一位'ELSE '不高于'END AS compare_salary
FROM employees

在这里插入图片描述

http://www.xdnf.cn/news/454051.html

相关文章:

  • 嵌入式(c语言篇)Day9
  • 基于nacos2.5.1的java微服务项目开发环境配置简介
  • Spyglass:跨时钟域同步(同步单元)
  • Gin 框架指南(代码+通俗解析版)
  • 2025前四月新能源汽车出口增长52.6%,外贸ERP数字化助力汽企持续跃升
  • 给 DBGridEh 增加勾选用的检查框 CheckBox
  • 通用软件项目技术报告 - 导读I
  • C++ 并发编程(1)再学习,为什么子线程不调用join方法或者detach方法,程序会崩溃? 仿函数的线程启动问题?为什么线程参数默认传参方式是值拷贝?
  • 阿里的库存秒杀实现与Inventory Hint技术解析
  • Windows系统Anaconda/Miniconda的安装、配置、基础使用、清理缓存空间和Pycharm/VSCode配置指南
  • Linux系统编程——fork函数的使用方法
  • idea插件使用
  • Prometheus 的介绍与部署(入门)
  • Spring 的 异常管理的相关注解@ControllerAdvice 和@ExceptionHandler
  • 2011-2019年各省总抚养比数据
  • 【GESP真题解析】第 5 集 GESP一级 2023 年 3 月编程题 2:长方形面积
  • Python实例题:Python抓取相亲网数据
  • Maplibgre-gl 学习1 初识
  • leetcode刷题日记——旋转链表
  • 深入理解Java HotSpot中的即时编译
  • 规控算法分类
  • 【Vue.js 的核心魅力:深入理解声明式渲染】
  • 学习黑客NFC技术详解
  • 互联网协议的多路复用、Linux系统的I/O模式
  • 【FileZilla】sftp协议的数据传输上传和下载
  • 软考软件设计师中级——软件工程笔记
  • QT---信号与槽
  • scons user 3.1.2
  • hls 的使用方式
  • ICML-2024《Image Clustering with External Guidance》