当前位置: 首页 > 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

在这里插入图片描述

相关文章:

  • 二叉树前序与后序遍历迭代法详解:栈操作与顺序反转的巧妙结合
  • 执行apt update后报错 Unable to lock directory /var/lib/apt/lists/ 问题解决
  • Myshell与清华联合开源TTS模型OpenVoiceV2,多语言支持,风格控制进一步增强~
  • leetcode2934. 最大化数组末位元素的最少操作次数-medium
  • 【工具类】ssh,remote-ssh插件和sftp插件
  • 基于EFISH-SCB-RK3576/SAIL-RK3576的智能安检机技术方案‌
  • electron结合vue,直接访问静态文件如何跳转访问路径
  • Apache Pulsar 消息、流、存储的融合
  • Spyglass:跨时钟域同步(同步单元)
  • 编程日志5.6
  • 一文掌握六个空转数据库
  • MySQL——九、锁
  • 十个免费试用的云数据库
  • 在 Windows 中配置使用 WSL 来运行 Linux 环境,主要有以下步骤:
  • 【测试开发知识储备】之Jacoco(Java Code Coverage)
  • LeetCode100.7 接雨水
  • 代码随想录算法训练营第60期第三十六天打卡
  • 【​​HTTPS基础概念与原理​】对称加密与非对称加密在HTTPS中的协作
  • 掌握Docker:从运行到挂载的全面指南
  • Openshift节点Disk pressure
  • “免签圈”扩容,旅游平台:今年以来巴西等国入境游订单显著增加
  • 上海锦江乐园摩天轮正在拆除中,预计5月底6月初拆完
  • 坚持吃素,是不是就不会得高血脂了?
  • 佩斯科夫:俄方代表团15日将在伊斯坦布尔等候乌克兰代表团
  • 山东:小伙为救同学耽误考试属实,启用副题安排考试
  • 台行政机构网站删除“汉人”改为“其余人口”,国台办回应