【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 ...
随机推荐
- Echart的简单例子
[转载自:http://echarts.baidu.com/echarts2/doc/start.html] <%@ page language="java" content ...
- linux rpm安装apache php mysql
CentOS 可以通过 yum 安装: yum -y install httpd php php-mysql mysql-serverservice httpd status|start|stop| ...
- Win7 64位下PowerDesigner连接64位Oracle11g数据库
操作系统:WIN7 64旗舰版 Oracle版本:64位11g PowerDesigner版本:15.1 问题描述:因为PowerDesigner是32的程序,连接数据库会默认开启32位的ODBC,因 ...
- golang笔记——array
1.定义一个 array 数组长度也是类型的一部分,比如长度为3的int数组与长度为5的int数组,并不是同一类型. package main import ( "strconv" ...
- Navigation Bar options for Android (based on photosomething project)
1, Tab控件即标签页,可以在一页中切换显示n页内容,要使用此效果,需要用到TabHost和Tabwidget类.(过时了?) Tab控件具有两种实现过程,一是在同一个Activity中切换显示不同 ...
- int类型的正负数转换
int aid = -this.id; 不能直接转 必须先赋值给一个变量 int c = this.id; int a = c * (-1); this.id = a;
- Android 全局获取 Context 与使用 Intent 传递对象
=====================全局获取 Context======================== Android 开发中很多地方需要用到 Context,比如弹出 Toast.启动活 ...
- django 模板语法和三种返回方式
模板 for循环 {% for athlete in athlete_list %} <li>{{ athlete.name }}</li> {% endfor %} if语句 ...
- 【转】android中ListView的定位:使用setSelectionFromTop实现ListView的position的保持
如果一个ListView太长,有时我们希望ListView在从其他界面返回的时候能够恢复上次查看的位置,这就涉及到ListView的定位问题: 解决的办法如下: 1 2 3 4 5 6 7 // 保存 ...
- iOS compare 字符串比较
NSString 比较字符串,我介绍一些常用的方法: NSString *value = @"1234567890"; 比较的方法: [value compare:(NSStrin ...