一篇文章看懂Oracle开窗函数
聚合类开窗函数
聚合类开窗函数类似分组函数group by中的sum()、avg()、count()、max()、min()等等。但是开窗函数不会像分组聚合函数一样按照分组返回结果,而是有多少行记录就返回多少个结果,结果输出的形式是单独一列进行输出。
举个例子:
这是普通的聚合函数
SELECT AVG(salary) FROM employees
这是最简单的聚合开窗函数
SELECT AVG(salary) over() FROM employees
从上面的例子可以看出,如果使用普通的聚合函数,在select后面加入其他列名,会提示“ORA-00937 不是单组分组函数”。
但是使用了开窗函数就可以为每行记录都匹配一个结果。
再举一个例子:
要求:查询姓名,部门ID,工资,部门的平均工资
如果用group by去实现的话,非常麻烦
首先要在子查询中求出每个部门的平均工资,然后再去和主查询进行关联,才能输出结果
SELECT last_name, emp.department_id, salary, emp.dept_avg_sal
FROM employees e,
(SELECT department_id, AVG(salary) dept_avg_sal
FROM employees
GROUP BY department_id) emp
WHERE e.department_id = emp.department_id
ORDER BY department_id;
如果使用开窗函数就非常容易实现了
只要在开窗函数中对部门ID进行分区就可以实现每一行查询结果都显示部门的平均工资
SELECT last_name,
department_id,
salary,
AVG(salary) over(PARTITION BY department_id) dept_avg_sal --相同部门ID的记录,在一个窗口中(窗口的概念后面会讲)
FROM employees
接下来我们通过几个例子来了解下开窗函数的组件作用
例1:查询每个雇员与自己薪水上下相差50元-150元之间的雇员数。
SELECT last_name,
salary,
COUNT(*) over(ORDER BY salary RANGE BETWEEN 50 preceding AND 150 following) mov_count
FROM employees;
Order by salary代表我们按照工资去进行排序,默认是是升序的,range between 50 preceding and 150 following代表取值的范围,也就是说我们要count的数量范围是比当前记录低50元和高150元区间内,这个50和150就是窗口的大小。
如果order by后面跟desc进行降序排列呢?那这个范围区间就改改过来变成range between 150 preceding and 50 following才行。
例2:查询50号部门中,每个员工比自己早入职的5个人和后入职的5个人的工资平均值,看看自己和他们之间的差距。
SELECT last_name,
department_id,
hire_date,
salary,
AVG(salary) over(PARTITION BY department_id ORDER BY hire_date rows BETWEEN 5 preceding AND 5 following) avg_sal
FROM employees
WHERE department_id = 50;
首先我们在开窗函数中使用了partition by对部门id进行分组,然后使用入职日期进行排序,这样就可以根据当前行的记录取这条记录的员工比他早入职的5个人和晚入职的5个人了。
在这个例子中我们使用了rows between这个子句,它的range between的区别是它的取值范围是前5条和后5条记录,而不是一个取值范围。5 preceding和5 following代表窗口的大小是5行记录。
例3:无边界窗口的演示
SELECT last_name,
hire_date,
salary,
AVG(salary) over(ORDER BY hire_date rows BETWEEN unbounded preceding AND unbounded following) c_mavg
FROM employees;
在例3中,我们对上一个例子做了一些修改,没有使用partition进行分区,直接按照入职日期进行排序,由于使用了unbounded这个子句则对于每一条记录而言,preceding和following是没有边界值的。所以这个例子中聚合开窗函数求的是全员的平均工资 avg(salary)。
接下来我们通过一个例子演示一下聚合类开窗函数的应用
应用例子:查询大于自己部门平均工资的员工信息,显示department_id,last_name,hire_date,salary,部门平均工资.
WITH dept_sal AS --建立一个临时表dept_sal
(SELECT department_id,
last_name,
hire_date,
salary,
AVG(salary) over(PARTITION BY department_id ORDER BY salary rows BETWEEN unbounded preceding AND unbounded following) avg_sal --求出分组中工资的平均值 用一列显示
FROM employees)
SELECT department_id, last_name, hire_date, salary, avg_sal
FROM dept_sal
WHERE salary > avg_sal --用临时表中的salary列比对avg_sal列
排序类开窗函数
RANK--序列集排序,相等值的行排名相同
--如果排名中,有相同的值,那么排名并列存在
--有几个并列存在的人,下一个排名就会顺延几个整数
SELECT e.department_id,
d.department_name,
e.last_name,
e.salary,
rank() over(PARTITION BY e.department_id ORDER BY e.salary) drank
FROM employees e, departments d
WHERE e.department_id = d.department_id
AND d.department_id IN (30, 40, 50);
DENSE_RANK--稠密排名
计算序组中的行的排名,排名从1开始的连续整数。
--按照department_id进行分组,salary进行排序
--关联员工表和部门表,关联条件department_id
--筛选出30 40 50三个部门的排名情况,以d_rank列输出排名情况
--遇到重复值全部并列进行排名
SELECT e.department_id,
d.department_name,
e.last_name,
e.salary,
dense_rank() over(PARTITION BY e.department_id ORDER BY e.salary) d_rank
FROM employees e, departments d
WHERE e.department_id = d.department_id
AND d.department_id IN (30, 40, 50);
ROW_NUMBER
--给你已定的排序组中,从1开始为每一行分配一个唯一的数字。
--不会有并列
SELECT e.department_id,
d.department_name,
e.last_name,
e.salary,
row_number() over(PARTITION BY e.department_id ORDER BY e.salary) drank
FROM employees e, departments d
WHERE e.department_id = d.department_id
AND d.department_id IN (30, 40, 50);
rank,dense_rank,row_number的比较:
SELECT employee_id,
last_name,
department_id,
salary,
rank() over(PARTITION BY department_id ORDER BY salary) "Rank",
dense_rank() over(PARTITION BY department_id ORDER BY salary) "D_rank",
row_number() over(PARTITION BY department_id ORDER BY salary) "Row_number"
FROM employees
WHERE department_id = 50;
ntile() 平均分组函数
--将30号部门的人,按照工资高低分为三个档
--将30号部门的人,按照工资高低分为三个档
SELECT last_name,
department_id,
salary,
ntile(3) over(PARTITION BY department_id ORDER BY salary) level_sal
FROM employees
WHERE department_id = 30;
一篇文章看懂Oracle开窗函数相关推荐
- 一篇文章看懂@Scheduled定时器/@Async/CompletableFuture
一篇文章看懂@Scheduled定时器/@Async/CompletableFuture @Scheduled注解解析: 1.cron:最重要的一个参数 cron表达式[秒] [分] [小时] [日] ...
- 一篇文章看懂变量提升(hoisting)
文章转自:一篇文章看懂变量提升(hoisting) - 知乎 前沿 大家对变量提升(hoisting)一定不陌生了,这篇文章希望可以建立一个系统的规则,以后碰到变量提升,可以重新看这篇文章,根据文中的 ...
- c++ socket线程池原理_一篇文章看懂 ThreadLocal 原理,内存泄露,缺点以及线程池复用的值传递问题...
编辑:业余草来源:https://www.xttblog.com/?p=4946 一篇文章看懂 ThreadLocal 原理,内存泄露,缺点以及线程池复用的值传递问题. ThreadLocal 相信不 ...
- 一篇文章看懂MySQL的多表连接(包含左/右/全外连接)
MySQL的多表查询 这是第二次学习多表查询,关于左右连接还是不是很熟悉,因此重新看一下.小目标:一篇文章看懂多表查询!! 这篇博客是跟着宋红康老师学习的,点击此处查看视频,关于数据库我放在了Gith ...
- 一篇文章看懂:量化交易
什么是量化交易? 度娘官方版 - 理论这么说 量化交易是指以先进的数学模型替代人为的主观判断,利用计算机技术从庞大的历史数据中海选能带来超额收益的多种"大概率"事件以制定策略,极大 ...
- 一篇文章看懂makefile编写规则
该篇文章为转载,是对原作者系列文章的总汇加上标注. 支持原创,请移步陈浩大神博客:(最原始版本) http://blog.csdn.net/haoel/article/details/2886 我转自 ...
- Java读取excel的方式,一篇文章看懂(详细)
目录 一.excel读取的两种方式 1.1 jxl 和 poi 的区别和选择 二.jxl 的使用 2.1 导入相关依赖 2.2 操作 三.poi 的使用 3.1 导入相关依赖 3.2 操作 四.总结 ...
- 一篇文章看懂select_poll_epoll
书上还有各种博客介绍select.poll.epoll基本上都是一上来就介绍数据结构,参数等等,这对新手很不友好啊,于是看到了知乎大神的帖子:https://www.zhihu.com/questio ...
- 一篇文章看懂有关iOS开发语言的一切!
看什么看!点我呀!全栈程序员,免费入门到精通! 作者丨开发之家 https://www.jianshu.com/p/1fd231cfe54b 前言 iOS开发语言有哪些?OS开发语言主要包括什么?iO ...
- python iterable对象_一篇文章看懂 Python iterable,
Python 中的 iterable, iterator 以及 generator,一直是非常亲密但是难以区分的概念.nvie 有一个很好的 帖子阐述了它们之间的关系,但是内容偏向于概括和总结,对于新 ...
最新文章
- 用TensorFlow实现自编码器Autoencoders
- CSS魔法堂:更丰富的前端动效by CSS Animation
- python多线程和多进程的区别_python中多线程与多进程的区别
- 【mongodb系统学习之六】mongodb配置文件方式启动
- excel行列互换_Excel如何实现行列数据互换?其实除了复制粘贴,还能这样操作...
- 计算机四级软件工程知识点,计算机四级考点
- python中text怎么旋转字体_Python+OpenCV实现旋转文本校正方式
- 须使用visual c 内联汇编语言开发,在VisualC 中使用内联汇编
- 动词ing基本用法_如果实在分不清英语动名词和现在分词,那就直接学习-ing分词...
- mysql 5.6.28安装图解_mysql 5.6.28 自动安装shell脚本
- 教育部计算机考研大纲,2018考研大纲从哪里看?
- 【Flink】Flink keyed State多年的误解 以及 Keyed state redistribute
- directx最终用户运行时_WSL将支持GPU计算,并可运行Linux GUI应用
- CentOS6.7安装Open***服务端
- 场景应用:100亿的数据你怎么排序
- Ubuntu下的几种常见输入法极其配置方式
- ros运行cpp文件
- redis读取连接超时问题
- 小米手机连接电脑只能看到部分相片_小米手机连接电脑后怎么看照片?
- HITB | 360议题分享:卫星可欺骗 地震警报可伪造