聚合类开窗函数

聚合类开窗函数类似分组函数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开窗函数相关推荐

  1. 一篇文章看懂@Scheduled定时器/@Async/CompletableFuture

    一篇文章看懂@Scheduled定时器/@Async/CompletableFuture @Scheduled注解解析: 1.cron:最重要的一个参数 cron表达式[秒] [分] [小时] [日] ...

  2. 一篇文章看懂变量提升(hoisting)

    文章转自:一篇文章看懂变量提升(hoisting) - 知乎 前沿 大家对变量提升(hoisting)一定不陌生了,这篇文章希望可以建立一个系统的规则,以后碰到变量提升,可以重新看这篇文章,根据文中的 ...

  3. c++ socket线程池原理_一篇文章看懂 ThreadLocal 原理,内存泄露,缺点以及线程池复用的值传递问题...

    编辑:业余草来源:https://www.xttblog.com/?p=4946 一篇文章看懂 ThreadLocal 原理,内存泄露,缺点以及线程池复用的值传递问题. ThreadLocal 相信不 ...

  4. 一篇文章看懂MySQL的多表连接(包含左/右/全外连接)

    MySQL的多表查询 这是第二次学习多表查询,关于左右连接还是不是很熟悉,因此重新看一下.小目标:一篇文章看懂多表查询!! 这篇博客是跟着宋红康老师学习的,点击此处查看视频,关于数据库我放在了Gith ...

  5. 一篇文章看懂:量化交易

    什么是量化交易? 度娘官方版 - 理论这么说 量化交易是指以先进的数学模型替代人为的主观判断,利用计算机技术从庞大的历史数据中海选能带来超额收益的多种"大概率"事件以制定策略,极大 ...

  6. 一篇文章看懂makefile编写规则

    该篇文章为转载,是对原作者系列文章的总汇加上标注. 支持原创,请移步陈浩大神博客:(最原始版本) http://blog.csdn.net/haoel/article/details/2886 我转自 ...

  7. Java读取excel的方式,一篇文章看懂(详细)

    目录 一.excel读取的两种方式 1.1 jxl 和 poi 的区别和选择 二.jxl 的使用 2.1 导入相关依赖 2.2 操作 三.poi 的使用 3.1 导入相关依赖 3.2 操作 四.总结 ...

  8. 一篇文章看懂select_poll_epoll

    书上还有各种博客介绍select.poll.epoll基本上都是一上来就介绍数据结构,参数等等,这对新手很不友好啊,于是看到了知乎大神的帖子:https://www.zhihu.com/questio ...

  9. 一篇文章看懂有关iOS开发语言的一切!

    看什么看!点我呀!全栈程序员,免费入门到精通! 作者丨开发之家 https://www.jianshu.com/p/1fd231cfe54b 前言 iOS开发语言有哪些?OS开发语言主要包括什么?iO ...

  10. python iterable对象_一篇文章看懂 Python iterable,

    Python 中的 iterable, iterator 以及 generator,一直是非常亲密但是难以区分的概念.nvie 有一个很好的 帖子阐述了它们之间的关系,但是内容偏向于概括和总结,对于新 ...

最新文章

  1. 用TensorFlow实现自编码器Autoencoders
  2. CSS魔法堂:更丰富的前端动效by CSS Animation
  3. python多线程和多进程的区别_python中多线程与多进程的区别
  4. 【mongodb系统学习之六】mongodb配置文件方式启动
  5. excel行列互换_Excel如何实现行列数据互换?其实除了复制粘贴,还能这样操作...
  6. 计算机四级软件工程知识点,计算机四级考点
  7. python中text怎么旋转字体_Python+OpenCV实现旋转文本校正方式
  8. 须使用visual c 内联汇编语言开发,在VisualC 中使用内联汇编
  9. 动词ing基本用法_如果实在分不清英语动名词和现在分词,那就直接学习-ing分词...
  10. mysql 5.6.28安装图解_mysql 5.6.28 自动安装shell脚本
  11. 教育部计算机考研大纲,2018考研大纲从哪里看?
  12. 【Flink】Flink keyed State多年的误解 以及 Keyed state redistribute
  13. directx最终用户运行时_WSL将支持GPU计算,并可运行Linux GUI应用
  14. CentOS6.7安装Open***服务端
  15. 场景应用:100亿的数据你怎么排序
  16. Ubuntu下的几种常见输入法极其配置方式
  17. ros运行cpp文件
  18. redis读取连接超时问题
  19. 小米手机连接电脑只能看到部分相片_小米手机连接电脑后怎么看照片?
  20. HITB | 360议题分享:卫星可欺骗 地震警报可伪造

热门文章

  1. smartPrinter安装报错
  2. 【君思智慧园区】园区物业管理系统,物业管理系统解决方案
  3. ubuntu下安装万能五笔
  4. 2018年,Windows Phone 8.1还能做什么
  5. 基于Android系统手机通讯录管理软件的设计与开发
  6. Linux系统下的文件和文件夹相关操作(创建/删除/修改权限)
  7. (动态示例)制作chm离线手册文件-w3school为例
  8. 中文文本情感分析:基于机器学习方法的思路
  9. 观点| 胡小明:不确定性环境下的智慧城市顶层设计
  10. 揭秘淘宝286亿海量图片存储与处理架构