转自:  https://blog.csdn.net/a1065423444/article/details/75635611

over()函数写法over(partition by expr2 order by expr3),根据expr2对结果进行分区,在各分区内按照expr3进行排序;

over函数不能单独使用,需要与row_number(),rank()和dense_rank,lag()和lead(),sum()等配合使用。

分区partiton by 与 group by的区别
group by会将结果集按照指定字段进行聚合,结果集会缩减,在统计部门人数,平均工资时会用到;
partition by会对结果集按照指定字段分层排列,结果集不会缩减,如将公司所有人按照部门进行分区,会发现结果集中同一部门的人会连续排列。

根据配合使用的函数情况的不同,分层次介绍:
- row_number(),rank(),dense_rank()
- lag()与lead()
- sum()

1、与row_number(),rank(),dense_rank()的使用
这三个函数与over连用时order by 不能丢失,不写partition by时默认结果集为一整个分区。
row_number()与over(partition exp2 order by exp3)配合使用可以对分区根据exp1进行排序,此排序是从1开始,即使遇到相同的数据,也区分开来排序。

SELECT e.employee_id,
e.department_id,
row_number() over(PARTITION BY e.department_id ORDER BY e.salary),
e.salary
FROM employees e;
1
2
3
4
5

rank()与over(partition exp2 order by exp3)配合使用可以对分区根据exp3进行可并列排序,此排序是从1开始,遇到相同的数据,会排成同一名,排名可能不连续。

SELECT e.employee_id,
e.department_id,
rank() over(PARTITION BY e.department_id ORDER BY e.salary),
e.salary
FROM employees e;
1
2
3
4
5
6

dense_rank()表示每一条数据在所属分区的等级

SELECT e.employee_id,
e.department_id,
dense_rank() over(PARTITION BY e.department_id ORDER BY e.salary),
e.salary
FROM employees e;
1
2
3
4
5

2、与lag()与lead()的使用
这两个函数与over连用时order by 不能丢失,不写partition by时默认结果集为一整个分区。
lag(expr1) over(partiton by expr2 order by expr3)
在分区内获取前一行数据的expr1字段的值,第一行为空(第一行无前一行)

SELECT e.employee_id,
e.department_id,
lag(e.department_id) over(PARTITION BY e.department_id ORDER BY e.salary)
FROM employees e;
1
2
3
4

lead(expr1) over(partiton by expr2 order by expr3)
在分区内获取后一行数据的expr1字段的值,最后一行为空(最后一行无后一行)

SELECT e.employee_id,
e.department_id,
lead(e.department_id) over(PARTITION BY e.department_id ORDER BY e.salary)
FROM employees e;
1
2
3
4

在此作用不太明显,但是若配合decode等来使用,会有不一样的效果,如可以将分区内重复的结果数据置为空。
结果如下:

代码如下:

SELECT decode(department, NULL, t.department_id, NULL) department_id,
decode(department, NULL, d.department_name, NULL) department_name,
decode(department, NULL, t.employee, NULL) employee,
decode(department, NULL, t.avg_s, NULL) avg_sal,
t.last_name,
t.salary,
t.job_id
FROM departments d,
(SELECT e.department_id,
e.last_name,
e.salary,
e.job_id,
avgs.avg_s,
avgs.employee,
lag(e.department_id) over(PARTITION BY e.department_id ORDER BY e.last_name) department --用于判断的别名
FROM employees e,
(SELECT e2.department_id, --部门工资平均值与部门人数
trunc(AVG(e2.salary), 2) avg_s,
COUNT(*) employee
FROM employees e2
GROUP BY e2.department_id) avgs
WHERE e.department_id = avgs.department_id) t
WHERE d.department_id = t.department_id;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
3、与sum()的使用
sum()与over连用时order by 可以不写,不写partition by时默认结果集为一整个分区;需要特别注意的是,此处的sum不是求整个分区的和,而是按照order by expr3字段进行分层后,求出分区中小于等于自身所在分层等级的和,即连续求和。
sum(expr1) over(partition by expr2 order by expr3)

不写order by字段,默认整个分区属于同一层
多个sum() over()连用时,分区只按照顺序出现的第一个order by进行排序;每个sum()计算的值,按自身的order by进行分层后计算,类似于使用一个子查询进行计算。

SELECT e.employee_id,
e.department_id,
e.salary,
SUM(e.salary) over(PARTITION BY e.department_id),
SUM(e.salary) over(PARTITION BY e.department_id ORDER BY e.salary)
FROM employees e
WHERE e.department_id = 100;
1
2
3
4
5
6
7

此时按照的是第二个sum+over的order by e.salary字段对分区进行的排序。(第一个sum+over无order by 字段)
对于第一个sum+over,默认为所有成员在同一层,所以第四列的值全为分区员工工资总和。

SELECT e.employee_id,
e.job_id,
e.salary,
SUM(e.salary) over(PARTITION BY e.department_id ORDER BY e.salary),
SUM(e.salary) over(PARTITION BY e.department_id ORDER BY e.job_id)
FROM employees e
WHERE e.department_id = 100;
1
2
3
4
5
6
7

此处结果集按照第一个sum+over的order by e.salary进行排序,第五列的结果是按照e.job_id进行分层后连续求和得到的,第一层job_id=FI_ACCOUNT,共五个,所以那五行的第五列结果都为第一层的和;job_id=FI_MGR属于按job_id分层的第二层,所以计算结果为第一层+第二层的连续求和。
---------------------
作者:kaiyeyou
来源:CSDN
原文:https://blog.csdn.net/a1065423444/article/details/75635611
版权声明:本文为博主原创文章,转载请附上博文链接!

Oracle数据库over函数的使用的更多相关文章

  1. Oracle数据库DECODE函数的使用.

    decode函数是Oracle数据库独有的. 语法为: decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值) 例子:select decode(sign(变量1-变量2) ...

  2. Oracle数据库to_date函数注意事项

    使用PL/SQL连接到Oracle数据库服务器,执行一条update语句: update pjnl set transtime = to_date('2015-05-14 12:13:20','yyy ...

  3. Mysql和Oracle数据库concat()函数

    一.函数的使用参数不同 Mysql支持多个字符串拼接: CONCAT(str1,str2,-) Oralce只支持两个字符串的拼接,若想拼接多个字符串可以嵌套使用concat CONCAT(str1, ...

  4. Oracle数据库--SQL函数

    Oracle SQL函数  1.ASCII返回与指定的字符对应的十进制数;SQL> select ascii('A') A,ascii('a') a,ascii('0') zero,ascii( ...

  5. Oracle数据库常用函数

    Oracle常用函数: 20.COS返回一个给定数字的余弦SQL> select cos(-3.1415927) from dual;COS(-3.1415927)--------------- ...

  6. Oracle数据库有用函数

    有用函数 DECODE 语法例如以下: DECODE(value, if1, then1, if2,then2,if3,then3, . . . else )  Value 代表某个表的不论什么类型的 ...

  7. Oracle数据库的函数

    一.字符函数upper和lower (1).upper和lower upper把小写的字符转换成大小的字符 ,lower把大写字符变成小写字符 . select upper('yes') from d ...

  8. ORACLE 数据库 MOD 函数用法

    1.求2和1的余数. Select mod(2,1) from dual: 2能被1整除所以余数为0. 2.MOD(x,y)返回X除以Y的余数.如果Y是0,则返回X的值. Select mod(2,0 ...

  9. Oracle数据库常用函数使用--持续更新中

    NVL函数.NVL( string1, replace_with).如果string1为NULL,则NVL函数返回replace_with的值,否则返回原来的值. INSTR函数.用于查找指定字符串是 ...

随机推荐

  1. 关于String类学习的一些笔记(本文参考来自程序员考拉的文章)

    String 类继承自 Object 超类,实现的接口有:Serializable.CharSequence.Comparable<String> 接口,具体如下图: 一.常用的Strin ...

  2. 【翻译】Flume 1.8.0 User Guide(用户指南) Processors

    翻译自官网flume1.8用户指南,原文地址:Flume 1.8.0 User Guide 篇幅限制,分为以下5篇: [翻译]Flume 1.8.0 User Guide(用户指南) [翻译]Flum ...

  3. flex弹性盒子布局

    一.在需要使用弹性盒子的容器上添加属性:display:flex 或者 display:inline-flex; 二.在父容器上添加flex-direction设置子元素主轴方向: 不写默认值是X轴从 ...

  4. excle记录

    比较两列不一样的数据 https://jingyan.baidu.com/article/fd8044fa23eef05030137a66.html

  5. PHP与Excel 笔记

    一:   PHP将数据导出Excel表中(投机型) 二: PHPExcel: Github上可以下载此插件包,用法如下: 前端: //上传阅卷员Excel文件 $("#upload_memb ...

  6. 计算机网络三:域名、IP地址和TCP/IP协议

    一.域名        域名(Domain Name),简称域名.网域,是由一串用点分隔的字符型标志名字组成的Internet上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位(有时 ...

  7. android-读取MediaProvider

    1.MediaProvider存储手机中的媒体文件,用 SQLite 数据库存储图片.视频.音频等多媒体文件的信息,供视频播放器.音乐播放器.图库使用.以 root 权限进入 adb shell,使用 ...

  8. easyui时的时间格式yyyy-MM-dd与yyyy-MM-ddd HH:mm:ss

    easyui日期的转换,日期汉化导入:<script type="text/javascript" src="../easyui/locale/easyui-lan ...

  9. 原生AJAX(包括Fetch)

    一.INTRO AJAX即“Asynchronous Javascript And XML” 一.Ajax的原生初级 1.1 Ajax对象创建:var xhr= new XMLHttpRequest( ...

  10. Leetcode(一)两数之和

    1.两数之和 题目要求: 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,你不能重 ...