注:标题中的红色order by是说明在使用该方法的时候必须要带上order by。

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

现在客户有这样一个需求,查询每个部门工资最高的雇员的信息,相信有一定oracle应用知识的同学都能写出下面的SQL语句:

[sql] view plaincopy
  1. select e.ename, e.job, e.sal, e.deptno
  2. from scott.emp e,
  3. (select e.deptno, max(e.sal) sal from scott.emp e group by e.deptno) me
  4. where e.deptno = me.deptno
  5. and e.sal = me.sal;

在满足客户需求的同时,大家应该习惯性的思考一下是否还有别的方法。这个是肯定的,就是使用本小节标题中rank() over(partition by...)或dense_rank() over(partition by...)语法,SQL分别如下:

[sql] view plaincopy
  1. select e.ename, e.job, e.sal, e.deptno
  2. from (select e.ename,
  3. e.job,
  4. e.sal,
  5. e.deptno,
  6. rank() over(partition by e.deptno order by e.sal desc) rank
  7. from scott.emp e) e
  8. where e.rank = 1;
[sql] view plaincopy
  1. select e.ename, e.job, e.sal, e.deptno
  2. from (select e.ename,
  3. e.job,
  4. e.sal,
  5. e.deptno,
  6. dense_rank() over(partition by e.deptno order by e.sal desc) rank
  7. from scott.emp e) e
  8. where e.rank = 1;

为什么会得出跟上面的语句一样的结果呢?这里补充讲解一下rank()/dense_rank() over(partition by e.deptno order by e.sal desc)语法。
over:   在什么条件之上。
partition by e.deptno:   按部门编号划分(分区)。
order by e.sal desc:   按工资从高到低排序(使用rank()/dense_rank() 时,必须要带order by否则非法)
rank()/dense_rank():   分级
整个语句的意思就是:在按部门划分的基础上,按工资从高到低对雇员进行分级,“级别”由从小到大的数字表示(最小值一定为1)。

那么rank()和dense_rank()有什么区别呢?
rank():  跳跃排序,如果有两个第一级时,接下来就是第三级。
dense_rank():  连续排序,如果有两个第一级时,接下来仍然是第二级。

小作业:查询部门最低工资的雇员信息。

二、min()/max() over(partition by ...)

现在我们已经查询得到了部门最高/最低工资,客户需求又来了,查询雇员信息的同时算出雇员工资与部门最高/最低工资的差额。这个还是比较简单,在第一节的groupby语句的基础上进行修改如下:

[sql] view plaincopy
  1. select e.ename,
  2. e.job,
  3. e.sal,
  4. e.deptno,
  5. e.sal - me.min_sal diff_min_sal,
  6. me.max_sal - e.sal diff_max_sal
  7. from scott.emp e,
  8. (select e.deptno, min(e.sal) min_sal, max(e.sal) max_sal
  9. from scott.emp e
  10. group by e.deptno) me
  11. where e.deptno = me.deptno
  12. order by e.deptno, e.sal;

上面我们用到了min()和max(),前者求最小值,后者求最大值。如果这两个方法配合over(partition by ...)使用会是什么效果呢?大家看看下面的SQL语句:

[sql] view plaincopy
  1. select e.ename,
  2. e.job,
  3. e.sal,
  4. e.deptno,
  5. nvl(e.sal - min(e.sal) over(partition by e.deptno), 0) diff_min_sal,
  6. nvl(max(e.sal) over(partition by e.deptno) - e.sal, 0) diff_max_sal
  7. from scott.emp e;

这两个语句的查询结果是一样的,大家可以看到min()和max()实际上求的还是最小值和最大值,只不过是在partition by分区基础上的。

小作业:如果在本例中加上order by,会得到什么结果呢?

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

中国人爱攀比,好面子,闻名世界。客户更是好这一口,在和最高/最低工资比较完之后还觉得不过瘾,这次就提出了一个比较变态的需求,计算个人工资与比自己高一位/低一位工资的差额。这个需求确实让我很是为难,在groupby语句中不知道应该怎么去实现。不过。。。。现在我们有了over(partition by ...),一切看起来是那么的简单。如下:

[sql] view plaincopy
  1. select e.ename,
  2. e.job,
  3. e.sal,
  4. e.deptno,
  5. lead(e.sal, 1, 0) over(partition by e.deptno order by e.sal) lead_sal,
  6. lag(e.sal, 1, 0) over(partition by e.deptno order by e.sal) lag_sal,
  7. nvl(lead(e.sal) over(partition by e.deptno order by e.sal) - e.sal,
  8. 0) diff_lead_sal,
  9. nvl(e.sal - lag(e.sal) over(partition by e.deptno order by e.sal), 0) diff_lag_sal
  10. from scott.emp e;

看了上面的语句后,大家是否也会觉得虚惊一场呢(惊出一身冷汗后突然鸡冻起来,这样容易感冒)?我们还是来讲解一下上面用到的两个新方法吧。
lead(列名,n,m):   当前记录后面第n行记录的<列名>的值,没有则默认值为m;如果不带参数n,m,则查找当前记录后面第一行的记录<列名>的值,没有则默认值为null。
lag(列名,n,m):   当前记录前面第n行记录的<列名>的值,没有则默认值为m;如果不带参数n,m,则查找当前记录前面第一行的记录<列名>的值,没有则默认值为null。

下面再列举一些常用的方法在该语法中的应用(注:带order by子句的方法说明在使用该方法的时候必须要带order by):

[sql] view plaincopy
  1. select e.ename,
  2. e.job,
  3. e.sal,
  4. e.deptno,
  5. first_value(e.sal) over(partition by e.deptno) first_sal,
  6. last_value(e.sal) over(partition by e.deptno) last_sal,
  7. sum(e.sal) over(partition by e.deptno) sum_sal,
  8. avg(e.sal) over(partition by e.deptno) avg_sal,
  9. count(e.sal) over(partition by e.deptno) count_num,
  10. row_number() over(partition by e.deptno order by e.sal) row_num
  11. from scott.emp e;

重要提示:大家在读完本片文章之后可能会有点误解,就是OVER (PARTITION BY ..)比GROUP BY更好,实际并非如此,前者不可能替代后者,而且在执行效率上前者也没有后者高,只是前者提供了更多的功能而已,所以希望大家在使用中要根据需求情况进行选择。

Oracle高级查询,over 用法相关推荐

  1. oracle高级查询案例,oracle高级查询(实例基于scott用户四张表)

    oracle高级查询(实例基于scott用户四张表) 分组查询 多表查询 子查询 综合实例 ====================================================== ...

  2. Oracle高级查询之over(partition by...) 分组排序

    Oracle高级查询之over(partition by...) 分组排序 一.rank()/dense_rank() over(partition by ...order by ...) 现在客户有 ...

  3. Oracle 模糊查询like用法

    一.我们可以在where子句中使用like关键字来达到Oracle模糊查询的效果:在Where子句中,可以对datetime.char.varchar字段类型的列用Like关键字配合通配符来实现模糊查 ...

  4. oracle高级查询用法

    2019独角兽企业重金招聘Python工程师标准>>> 层次化查询 有下图这样一张表,它记录的是员工的一些信息,m_id该员工的上级的id,例如James就是Ron的上级: 那么我们 ...

  5. oracle—高级查询

    Sql基础 数据库语言 数据操纵语言:DML (data manipulation language) select insert update delete merge 数据定义语言:DDL(dat ...

  6. Oracle高级查询

    使用Oracle特有的查询语法, 可以达到事半功倍的效果 1. 树查询 create table tree (     id number(10) not null primary key,      ...

  7. Oracle高级查询之over(partition by..)

    查看原文:http://ibloger.net/article/248.html 为了方便学习和测试,所有的例子都是在Oracle自带用户Scott下建立的. create table EMP (em ...

  8. 傅老师课堂:Oracle高级查询之CONNECT BY

    为了方便大家学习和测试,所有的例子都是在Oracle自带用户Scott下建立的. Oracle中的select语句可以用start with ... connect by prior ...子句实现递 ...

  9. 傅老师课堂:Oracle高级查询之OVER (PARTITION BY ..)

    [size=large][size=large][size=large]开篇一笑:某日一妹子对男友说:在一起这么久了你都没有夸过我漂亮,今天我要你夸夸我,男子想了一会看着女友鸡冻的说道:我硬了. 为了 ...

最新文章

  1. 中超赛程来100wan点in_不干了:中超球队改名“硬重启”,球迷组织绝望解散
  2. 如何使用WindowsLiveWriter发文章
  3. LVS学习笔记--概念
  4. python库整理:os
  5. Android Animation动画效果简介
  6. pythonos模块_Python3 入门教程——os模块使用(文件/目录操作)
  7. hive 窗口函数_Datatist科技专栏 | Hive排序窗口函数速学教程!
  8. 什么是IPsec协议
  9. 主管问我:你以为单元测试,只是测试吗?
  10. java09数组的使用
  11. 北京交大计算机学院院长,蔡伯根(北京交大教授)
  12. (转)一段如何調用Button.Click事件的故事
  13. html 数据库 编写学生表,【数据库】用sql语句创建学生表如何做
  14. PHP后台管理登录界面代码
  15. web 打开pdf文件
  16. launcher3的具体学习
  17. 【Unity3D】sRGB伽马(gamma)空间和sRGB Frame Buffer线性空间的简单介绍
  18. 经纪业务部负责人是什么工作
  19. php array assoc,PHP array_uintersect_assoc() 函数
  20. js 系统教程-15-js 语法之命令行-console.log,console.info,console.error,console.warn,debugger

热门文章

  1. STC8学习4 ——PWM波形应用
  2. 湖南大学计算机专业保研,湖南大学各专业保研率
  3. 完了!CPU一味求快出事儿了!
  4. 2011百度实习生招聘笔试试题---软件测试—测试方向(BJ)
  5. 【转】如何在IIS7或IIS7.5中导入导出站点及应用程序池
  6. 开启投简历找工作新征程
  7. 微信开发详解scope---snsapi_base和snaspi_userinfo 区别
  8. 中国1,2-己二醇市场趋势报告、技术动态创新及市场预测
  9. OA系统开发人事模块关于请假跨月的处理
  10. Gephi (网络分析软件) 下载、安装及简单使用