over() (分析函数)

news/2025/1/21 8:57:30/文章来源:https://www.cnblogs.com/TMesh/p/18682841

目录
  • 演示数据
  • rank()/dense_rank()
    • 示例
      • 根据 salary 排序,跳过同级
    • 根据 salary 排序,不跳过同级
  • min()/max()
    • 示例
      • 取每个 team 中 salary 最大的
      • 取每个 team 中 salary 最小的
  • lead()/lag()
    • 示例
      • 查询 salary 与比自己高一位、低一位的 salary 的差额
  • first_value()/last_value()
    • 示例
  • row_number()
    • 示例
      • sum/avg/count()
    • 示例
  • rows/range
    • 示例
  • nulls first/last
    • 示例
  • ntile(n)
    • 示例
  • keep(dense_rank first/last)
    • 示例

聚合函数(如 sum()、max() 等)可以计算基于组的某种聚合值,但是聚合函数对于某个组只能返回一行记录。若想对于某组返回多行记录,则需要使用分析函数

演示数据

create table rownumber(id varchar(10) not null,name varchar(10) null,age varchar(10) null,salary int null,team varchar(10) null
);insert into rownumber(id,name,age,salary,team) values(1,'a',10,8000, 'a');
insert into rownumber(id,name,age,salary,team) values(2,'a2',11,7500, 'a');
insert into rownumber(id,name,age,salary,team) values(3,'b',12,7500, 'b');
insert into rownumber(id,name,age,salary,team) values(4,'b2',13,4500, 'b');
insert into rownumber(id,name,age,salary,team) values(5,'c',14,8000, 'c');
insert into rownumber(id,name,age,salary,team) values(6,'c2',15,20000, 'c');
insert into rownumber(id,name,age,salary,team) values(7,'d',16,30000, 'd');
insert into rownumber(id,name,age,salary,team) values(8,'d2',17,8000, 'd');select * from rownumber;

![[Pasted image 20241202143656.png]]

rank()/dense_rank()

rank()/dense_rank over(partition by ... order by ...)

说明:

  • over() 在什么条件之上;
  • partition by 按哪个字段划分组(如果要分组必须,有此关键字 partition);
  • order by 按哪个字段排序;
    注意:
  • 使用 rank()/dense_rank() 时,必须要带 order by 否则非法
  • rank()/dense_rank() 分级的区别:

rank(): 跳跃排序,如果有两个第一级时,接下来就是第三级。
dense_rank():连续排序,如果有两个第一级时,接下来仍然是第二级。

示例

根据 salary 排序,跳过同级

select id, name, age, salary, team, rank() over(order by salary desc) as "rank" 
from rownumber

![[Pasted image 20241202142224.png]]

根据 salary 排序,不跳过同级

select id, name, age, salary, team, dense_rank() over(order by salary desc) as "rank" 
from rownumber

![[Pasted image 20241202142235.png]]

min()/max()

min()/max() over(partition by ... order by ...)

说明:

  • over() 在什么条件之上;
  • partition by 按哪个字段划分组(如果要分组必须,有此关键字 partition);
  • order by 按哪个字段排序;

示例

取每个 team 中 salary 最大的

select * from (select id, name, age, salary, team, max(salary) over(partition by team order by salary desc) as "rank" from rownumber) res 
where res.rank = res.salary;

![[Pasted image 20241202142210.png]]

取每个 team 中 salary 最小的

select * from (select id, name, age, salary, team, min(salary) over(partition by team order by salary asc) as "rank" from rownumber) res 
where res.rank = res.salary;

![[Pasted image 20241202142036.png]]

lead()/lag()

lead()/lag() over(partition by ... order by ...) 

前面/后面n行记录说明:

  • lead(列名,n,m): 当前记录后面第 n 行记录的列名的值,没有则默认值为 m;如果不带参数 n,m,则查找当前记录后面第一行的记录列名的值,没有则默认值为 null。
  • lag(列名,n,m): 当前记录前面第n行记录的列名的值,没有则默认值为m;如果不带参数 n,m,则查找当前记录前面第一行的记录列名的值,没有则默认值为 null

示例

查询 salary 与比自己高一位、低一位的 salary 的差额

select id, name, age, salary, team, lead(salary, 1, 0) over(partition by team order by salary asc) as lead_sal, --记录后面第n行记录lag(salary, 1, 0) over(partition by team order by salary asc) as lag_sal --记录前面第N行记录
from rownumber;

![[Pasted image 20241202142718.png]]

first_value()/last_value()

取首尾记录

first_value()/last_value() over(partition by ... order by ...) 

示例

select id, name, age, salary, team, first_value(salary) over(partition by team) as first_sal,last_value(salary) over(partition by team) as last_sal
from rownumber;

![[Pasted image 20241202143155.png]]

row_number()

row_number() over(partition by ... order by ...) 

排序(应用:分页)

示例

select id, name, age, salary, team, row_number() over(partition by team order by salary) as row_num
from rownumber;

![[Pasted image 20241202143434.png]]

sum/avg/count()

sum/avg/count() over(partition by ..)

示例

select id, name, age, salary, team, sum(salary) over(partition by team) as sum_sal,			--统计某组中的总计值avg(salary) over(partition by team) as avg_sal,			--统计某组中的平均值count(salary) over(partition by team) as count_sal	--按某列分组,并统计该组中记录数量
from rownumber;

![[Pasted image 20241202143638.png]]

rows/range

rows/range  between … preceding and … following

上下范围内求值说明:

  • unbounded:不受控制的,无限的
  • preceding:在…之前
  • following:在…之后

示例

select id, name, age, salary, team, max(salary) over(partition by team order by salary rows --unbounded preceding and unbounded following针对当前所有记录的前一条、后一条记录,也就是表中的所有记录 --unbounded:不受控制的,无限的 --preceding:在...之前 --following:在...之后between unbounded preceding and unbounded following) as max_sal
from rownumber;

![[Pasted image 20241202144318.png]]

nulls first/last

将空值字段记录放到最前或最后显示
说明:通过 rank()、dense_rank()、row_number() 对记录进行全排列、分组排列取值,但有时候,会遇到空值的情况,空值会影响得到的结果的正确性
nulls first/last 可以帮助我们在处理含有空值的排序排列中,将空值字段记录放到最前最后显示,帮助我们得到期望的结果

示例

select id, name, age, salary, team, rank() over(partition by team order by salary desc nulls last) as "rank" 
from rownumber

ntile(n)

有时会有这样的需求:如果数据排序后分为三部分,业务人员只关心其中的一部分,如何将这中间的三分之一数据拿出来呢?
这时比较好的选择,就是使用 ntile 函数

示例

select id, name, age, salary, team, max(salary) over(partition by team order by salary rows between unbounded preceding and unbounded following) as max_salntile(3) over(order by salary desc nulls last) all_cmp, --若只取前三分之一,all_cmp=1即可,若只取中间三分之一,all_cmp=2即可ntile(3) over(partition by team order by salary desc nulls last) all_team  --每个team的分成三部分
from rownumber;

keep(dense_rank first/last)

keep字面意思就是保持,也就是说保存满足 keep()括号内条件的记录,这里可以想象到,会有多条记录的情况,即存在多个 last 或 first 的情况

  • dense_rank 是排序策略
  • first/last 是筛选策略

示例

select id, name, age, salary, team, min(salary) keep(dense_rank first order by salary) min_sal
from rownumber;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/872644.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WebStorm 2024.3.1 前端开发工具

WebStorm 2024.3.1 前端开发工具 JetBrains WebStorm 2024 mac,是一款JavaScript开发工具,WebStorm 非常了解您的项目结构,可以在编码的各个方面提供帮助。它将自动补全代码,检测错误和冗余并提出修正建议,帮助您安全地重构代码。

MySQL数据库开启远程访问权限

1、背景描述 默认情况下,MySQL 只允许本地登录,即只能在安装 MySQL 数据库所在的主机环境中访问。 在实际开发和使用中,一般需要访问远程服务器的数据库,此时就需要开启服务器端 MySQL 的远程访问权限。 2、查看MySQL的用户表如上图所示,Host 列指定了允许用户登录所使用的…

如何高效且安全地进行网站页面模板的修改?

在现代网站建设中,页面模板的修改是提升用户体验、优化SEO排名以及保持网站美观度的重要手段。以下是详细的步骤:备份现有模板:在开始任何修改之前,请确保已经对当前使用的模板进行了完整备份。这可以防止意外错误导致的数据丢失。 选择合适的编辑工具:根据所用的内容管理…

掌握这些技巧,让你轻松应对网站模板修改中的常见挑战

注意事项 解释遵循最佳实践 始终按照官方文档推荐的方式来进行修改,避免直接编辑核心文件,以减少升级时出现问题的风险。考虑SEO影响 模板中的元标签、标题标签等元素直接影响搜索引擎抓取效率,因此在修改时要格外小心,确保不会破坏原有SEO设置。维护一致性 整个网站应该保…

如何修改网站首页背景?

修改网站首页背景可以通过CSS或HTML实现。以下是具体步骤:使用CSS修改背景:打开网站的CSS文件(通常是style.css)。 找到控制背景的CSS规则,例如:body {background-image: url(images/background.jpg);background-size: cover;background-repeat: no-repeat; }修改backgro…

网站修改与上传的步骤

网站修改与上传的步骤如下:首先,确定需要修改的内容,并在本地开发环境中进行修改。可以使用文本编辑器或集成开发环境(IDE)来编辑网站文件。修改完成后,进行本地测试,确保修改后的网站功能和性能正常。然后,将修改后的文件上传到服务器。可以使用FTP客户端或服务器管理…

网站首页源码修改后不变的处理方法

网站首页源码修改后不变可能是由于缓存或编译问题导致的。首先,尝试清除浏览器缓存和网站缓存。可以在浏览器中按下Ctrl+Shift+Delete组合键,选择清除缓存选项,然后刷新网站。如果问题仍然存在,可能是服务器端缓存或编译的问题。可以尝试重启服务器或清除服务器缓存。如果使…

怎么修改自己公司的网站:全面更新网站内容和设计

问题描述 修改自己公司的网站可以帮助提升品牌形象和用户体验。这通常涉及更新网站内容、设计和功能。 解决方案规划修改内容制定详细的修改计划,包括需要更新的内容、设计元素、功能模块等。备份现有数据在进行任何修改之前,请确保已经完整备份了当前的网站数据。登录后台管…

如何使用Adobe Dreamweaver工具修改网站代码,确保网站正常运行?

Adobe Dreamweaver是一款强大的网页设计和开发工具,适合初学者和专业人士使用。以下是使用Dreamweaver修改网站代码的详细步骤和注意事项:安装Dreamweaver:首先,下载并安装Adobe Dreamweaver软件。确保安装过程中选择正确的安装选项。 连接到服务器:打开Dreamweaver,点击…

如何在织梦CMS网站中修改搜索框,以满足特定需求?

织梦CMS是一款流行的中文内容管理系统,广泛应用于企业网站和新闻站点。以下是修改织梦网站搜索框的详细步骤和注意事项:确定搜索框位置:首先,确定搜索框在网站中的位置。通常,搜索框位于页眉或页脚区域。 找到模板文件:打开织梦CMS的模板文件夹,找到包含搜索框的模板文件…

如何解决网站首页无法修改的问题,确保网站正常运行?

网站首页无法修改可能是由多种原因引起的,包括权限问题、文件损坏、服务器配置错误等。以下是解决网站首页无法修改问题的详细步骤和注意事项:检查文件权限:确保你有权限修改首页文件。通常,首页文件位于网站的根目录下,文件名可能是index.html、index.php等。 检查文件损…