【Oracle】oracle取最大值和最小值的几个方法汇总
(1)oracle使用keep分析函数取最值记录
-- 取工资sal最大的雇员姓名及其工资,以及工资sal最少的雇员姓名及其工资
select
deptno,
empno,
ename,
sal,
max(ename) keep(dense_rank FIRST order by sal) over (partition by deptno) as min_sal_man,
max(sal) keep(dense_rank FIRST order by sal) over (partition by deptno) as min_sal,
max(ename) keep(dense_rank LAST order by sal) over (partition by deptno) as max_sal_man,
max(sal) keep(dense_rank LAST order by sal) over (partition by deptno) as max_sal
from emp
where deptno=10
结果如下:

从语句中可以看到,ename和sal都是用的max(),这样做的目的是为了去除由于keep()函数得到的有重复值的数据结果集。这样用有一个弊端,加入部门20有两个相同的最大SAL的人,部门30有两个相同的最小SAL的人,如果按照这种方法取出来的数据,就不一定准确了,重复的人会被去除掉。
我们用下面的语句来修改一下:
select
deptno,
empno,
ename,
sal,
max(ename) keep(dense_rank FIRST order by sal) over (partition by deptno) as min_sal_man,
max(sal) keep(dense_rank FIRST order by sal) over (partition by deptno) as min_sal,
max(ename) keep(dense_rank LAST order by sal) over (partition by deptno) as max_sal_man,
max(sal) keep(dense_rank LAST order by sal) over (partition by deptno) as max_sal,
wmsys.wm_concat(ename) keep(dense_rank LAST order by sal) over (partition by deptno) as 工资最高的人,
wmsys.wm_concat(ename) keep(dense_rank FIRST order by sal) over (partition by deptno) as 工资最低的人
from emp
where deptno=20
order by 1, 2 ;
我们新增了两个列:工资最高的人,工资最低的人。执行看一下结果:

可以看到,deptno=20时,SCOTT和FORD两个人的工资SAL都是3000,如果用MAX()就只能取出其中一个人的姓名,显然是不对的。
然后,我们再来看一下deptno=30时的情况:
select
deptno,
empno,
ename,
sal,
max(ename) keep(dense_rank FIRST order by sal) over (partition by deptno) as min_sal_man,
max(sal) keep(dense_rank FIRST order by sal) over (partition by deptno) as min_sal,
max(ename) keep(dense_rank LAST order by sal) over (partition by deptno) as max_sal_man,
max(sal) keep(dense_rank LAST order by sal) over (partition by deptno) as max_sal,
wmsys.wm_concat(ename) keep(dense_rank LAST order by sal) over (partition by deptno) as 工资最高的人,
wmsys.wm_concat(ename) keep(dense_rank FIRST order by sal) over (partition by deptno) as 工资最低的人
from emp
where deptno=30
order by 1, 2 ;
deptno=30时的结果如下:

可以看到,deptno=30时,WARD和MARTIN两人的工资最小且均为1250,如果用MAX()的方式,就只能取出其中一个人的名称。
这就是因为keep()取出来的数据集是包含多个数据结果的,所以,在语句中使用了wmsys.wm_concat()函数,该函数的作用是以逗号分隔连接列的值。
注:wm_concat()的功能有点儿类似分析函数listagg() within group() 。
(2)使用SQL子查询和聚合函数,查询出最大值和最小值
-- 使用子查询查询出最大值和最小值
select * from
(
select
deptno,
listagg(ename,',') within group (order by deptno) as dept_max_ename,
max(sal) as dept_max_sal
from emp
where (deptno,sal) in (select deptno, max(sal) as max_sal from emp group by deptno)
group by deptno
) A
inner join
(
select
deptno,
listagg(ename,',') within group (order by deptno) as dept_min_ename,
min(sal) as dept_min_sal
from emp
where (deptno,sal) in (select deptno, min(sal) as min_sal from emp group by deptno)
group by deptno
) B
on A.deptno = B.deptno
结果如下:

在这个方案里面,还使用了listagg()分析函数将最值有重复姓名的人合并在一起,用wm_concat()函数替代listagg()也可以
wm_concat(ename) as dept_max_ename,
wm_concat(ename) as dept_min_ename,
------------------------------------------------------------------------
【Oracle】oracle取最大值和最小值的几个方法汇总的更多相关文章
- [sql server、oracle] 分组取最大值最小值常用sql
sqlserver2005前: --分组取最大最小常用sql--测试环境if OBJECT_ID('tb') is not null drop table tb;gocreate table tb( ...
- javascript 从对象数组中 按字段/属性取最大值或最小值
var array=[ { "index_id": 119, "area_id": "18335623", "name" ...
- Java 抓取 thread dump (Full Thread Stack Trace) 方法汇总
顾名思义,表示一个时间点上,显示进程里面每一个线程的 stack trace,以及线程之间关联,比如等待 常用来定位一些 不响应,CPU 很高,内存使用很高问题 汇总表格如下 工具 操作系统 Java ...
- 在含有null值的复杂类的集合(Collection)中取最大值
在日常编程中,经常遇到要在一组复杂类的集合(Collection)中做比较.取最大值或最小值. 举个最简单的例子,我们要在一个如下结构的集合中选取包含最大值的元素: public class Clas ...
- poj3264 最大值与最小值的差
For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. One d ...
- 【转】oracle 中随机取一条记录的两种方法
oracle 中随机取一条记录的两种方法 V_COUNT INT:=0; V_NUM INT :=0; 1:TBL_MYTABLE 表中要有一个值连续且唯一的列FID BEGIN SELECT COU ...
- 转载——JavaScript学习笔记:取数组中最大值和最小值
转载自:http://www.w3cplus.com/javascript/calculate-the-max-min-value-from-an-array.html. 取数组中最大值 可以先把思路 ...
- JavaScript学习:取数组中最大值和最小值
在实际业务中有的时候要取出数组中的最大值或最小值.但在数组中并没有提供arr.max()和arr.min()这样的方法.那么是不是可以通过别的方式实现类似这样的方法呢?那么今天我们就来整理取出数组中最 ...
- oracle 分组取第一行数据 ,查询sql语句
oracle 分组取第一行数据 SELECT * FROM ( SELECT ROW_NUMBER() OVER(PARTITION BY x ORDER BY y DESC) rn, t.* FR ...
随机推荐
- Windows操作系统待整理
12. 2001年10月25日Windows XP发布,Windows XP是基于Windows 2000代码的产品,同时拥有一个新的用户图形界面(叫做月神Luna),它包括了一些细微的修改.集成了防 ...
- 关于Java集合的小抄
在尽可能短的篇幅里,将所有List.Map.Set.Queue的特征与实现方式捋一遍.适合所有"精通Java"其实还不那么自信的人阅读. List ArrayList 以数组实现. ...
- Zabbix 监控 Nginx(四)
简介: 如何使用 Zabbix 监控 Nginx 状态 ? 1.获取 Nginx 状态( HTTP Stub Status ) [root@localhost ~]# /apps/product/ng ...
- SSH搭建
1.首先在lib中导入ssh需要的jar包: 如图: 2.其次配置web.xml (在WEB-INF目录下) <?xml version="1.0" encoding=&qu ...
- [Scala] Scala基础知识
Object An object is a type of class that can have no more than one instance, known in object-oriente ...
- 10款最好的 Bootstrap 3.0 免费主题和模板
Twitter Bootstrap 框架已经广为人知,用于加快网站,应用程序或主题的界面开发,并被公认为是迄今对于Web开发的最有实质性帮助的工具之一.在此之前的,各种各样的界面库伴随着高昂的维护成本 ...
- XML-->DTD&Schema Notes
The need for XML “schemas” •Unlike any other data format, XML is totally flexible, elements can be ...
- PHP大数(浮点数)取余
一般我们进行取余运算第一个想到的就是用百分号%,但当除数是个很大的数值,超出了int范围时,这样取余就不准确了. php大数(浮点数)取余函数 /** * php大数取余 * * @param int ...
- Linux进程间通信(四):命名管道 mkfifo()、open()、read()、close()
在前一篇文章—— Linux进程间通信 -- 使用匿名管道 中,我们看到了如何使用匿名管道来在进程之间传递数据,同时也看到了这个方式的一个缺陷,就是这些进程都由一个共同的祖先进程启动,这给我们在不相关 ...
- jquery写简单的div切换
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...