返回顶部
首页 > 资讯 > 数据库 >Oracle高级查询之OVER (PARTITION BY ..)
  • 938
分享到

Oracle高级查询之OVER (PARTITION BY ..)

2024-04-02 19:04:59 938人浏览 安东尼
摘要

为了方便大家学习和测试,所有的例子都是在Oracle自带用户Scott下建立的。注:标题中的红色order by是说明在使用该方法的时候必须要带上order by。一、rank()/de

为了方便大家学习和测试,所有的例子都是在Oracle自带用户Scott下建立的。

注:标题中的红色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;  


您可能感兴趣的文档:

--结束END--

本文标题: Oracle高级查询之OVER (PARTITION BY ..)

本文链接: https://lsjlt.com/news/37450.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Oracle高级查询之OVER (PARTITION BY ..)
    为了方便大家学习和测试,所有的例子都是在Oracle自带用户Scott下建立的。注:标题中的红色order by是说明在使用该方法的时候必须要带上order by。一、rank()/de...
    99+
    2024-04-02
  • Oracle 笔记之高级查询
    为列起别名目的 我们进行查询时 经常查询某一列时使用的是表达式 SELECT enamme,sal*12 FROM emp这样不好的地方是第二列在查询后列用使用的就是sal*12.这样的可读性比较差...
    99+
    2024-04-02
  • Oracle高级查询
    本章将学习的内容有:如何使用集合操作符,集合操作符用于将两个或多个查询返回的行组合起来使用TRANSLATE函数1、使用集合操作符    操作符说明UNION...
    99+
    2024-04-02
  • Oracle查询中OVER有哪些用法
    Oracle查询中OVER有哪些用法?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。注:标题中的红色order by是说明在使用...
    99+
    2024-04-02
  • MySQL之group by分组查询
    有如下数据: 一个简单的分组查询的案例 按照部门编号deptno分组,统计每个部门的平均工资。 select deptno,avg(sal) avgs from emp group by deptno; 结果如下: gro...
    99+
    2015-05-12
    MySQL之group by分组查询
  • Mongo高级查询
    1、条件操作符(1)条件操作符db.collection.find({ "field" : { $gt: value } } ); // 大于: field > valuedb.collection....
    99+
    2024-04-02
  • mongodb高级查询
      MongoDB 的逻辑结构是一种层次结构。主要由文档(document)、集合(collection)、数据库(database)这三部分组成的。逻辑结构是面向用户的用户使用MongoDB 开...
    99+
    2024-04-02
  • 怎么在Oracle中使用OVER查询语句
    本篇文章为大家展示了怎么在Oracle中使用OVER查询语句,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。一、rank()/dense_rank() over(pa...
    99+
    2024-04-02
  • T-SQL 高级查询
    T-SQL高级查询函数:是一个可反复使用的程序段从其他的程序段中使用调用语句来执行这段程序提前写好一段语句,取一个名字,使用时调用这个名字系统函数:转换数据类型,以及查看系统参数Convert():数据类型...
    99+
    2024-04-02
  • Oracle递归查询connect by用法
    目录一、概述1、层级查询的基本语法:二、使用1、基本用法2、SYS_CONNECT_BY_PATH() 函数3、CONNECT_BY_ISLEAF 伪列4、CONNECT_BY_RO...
    99+
    2024-04-02
  • mongodb高级聚合查询
      https://www.cnblogs.com/zhoujie/p/mongo1.html mongodb高级聚合查询     在工作中会经常遇到一些mongodb的聚合操作,特此总结下。mongo存储的可以是复杂类型,比...
    99+
    2016-06-26
    mongodb高级聚合查询
  • oracle之sql查询
    oracle表管理表名和列的命名规则:必须以字母开头长度不能超过30字符不能使用oracle的保留字只能使用如下字符:A-Z,a-z,0-9,$,#等字符型:char:定长 最大2000字符例子:cha&#...
    99+
    2024-04-02
  • SQL Server高级进阶之索引优化查询
    1.1、查找缺失索引 SELECT A.USER_SEEKS 查找次数,A.USER_SCANS 扫描次数, ROUND(A.AVG_TOTAL_USER_COST,2) 减少的用户查询的平均成本,A.AVG_USER_...
    99+
    2014-08-11
    SQL Server高级进阶之索引优化查询
  • MYSQL高级文本查询之regexp_like和REGEXP详解
    目录LIKE操作符CONCAT函数RLIKE操作符在MySQL中,regexp_like和REGEXP都是用于执行正则表达式搜索的函数。虽然它们都可以完成相似的任务,但它们之间还是有...
    99+
    2023-05-19
    mysql regexp_like和REGEXP mysql 文本查询regexp_like和REGEXP
  • 浅谈 T-SQL高级查询
    之前我们简单的了解了增、删、改、查这几类T-SQL语法来操纵数据表,但是为了更方便快捷地完成大量任务,SQL Server 提供了一些内部函数,可以和SQL Server 的SELECT语句来联合使...
    99+
    2024-04-02
  • Mybatis-Plus高级查询LambdaQueryWrapper&QueryWrapper
    目录 前言 Wrapper 查询构造器 查询条件 前期准备 查询条件 allEq eq ne gt ge lt le between,notBetween like,notLike likeLeft likeRight isNull 空值...
    99+
    2023-08-31
    mysql 数据库 mybatis
  • 【MySQL】细谈SQL高级查询
    文章目录 一、前言 & 准备工作二、简易高级查询⚙ 准备工作1、查询每一门课程及其先修课程2、查询和“刘涛”在一个班级的学生的信息3、查询选修了‘计算机基础’课的学生的学号、姓名③ 连接方式④ 子查询嵌套方式 4、查询没有...
    99+
    2023-12-23
    mysql sql 数据库
  • Oracle怎么查询Interval partition分区表内数据
    本篇内容介绍了“Oracle怎么查询Interval partition分区表内数据”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家...
    99+
    2024-04-02
  • oracle之sql查询二
    此文章为http://huangsir007.blog.51cto.com/6159353/1854818该片的后续 关于数据库语言查询:SQL> show parameter nls_languag...
    99+
    2024-04-02
  • Oracle 查询转换之子查询展开
    概念:子查询展开(Subquery Unnesting)是优化器处理带子查询的目标sql的一种优化手段,它是指优化器不再将目标sql中子查询当作一个独立的处理单元来单独执行,而是将该子查询转换为它自身和外部...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作