(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取最大值和最小值的几个方法汇总的更多相关文章

  1. [sql server、oracle] 分组取最大值最小值常用sql

    sqlserver2005前: --分组取最大最小常用sql--测试环境if OBJECT_ID('tb') is not null drop table tb;gocreate table tb(  ...

  2. javascript 从对象数组中 按字段/属性取最大值或最小值

    var array=[ { "index_id": 119, "area_id": "18335623", "name" ...

  3. Java 抓取 thread dump (Full Thread Stack Trace) 方法汇总

    顾名思义,表示一个时间点上,显示进程里面每一个线程的 stack trace,以及线程之间关联,比如等待 常用来定位一些 不响应,CPU 很高,内存使用很高问题 汇总表格如下 工具 操作系统 Java ...

  4. 在含有null值的复杂类的集合(Collection)中取最大值

    在日常编程中,经常遇到要在一组复杂类的集合(Collection)中做比较.取最大值或最小值. 举个最简单的例子,我们要在一个如下结构的集合中选取包含最大值的元素: public class Clas ...

  5. poj3264 最大值与最小值的差

    For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. One d ...

  6. 【转】oracle 中随机取一条记录的两种方法

    oracle 中随机取一条记录的两种方法 V_COUNT INT:=0; V_NUM INT :=0; 1:TBL_MYTABLE 表中要有一个值连续且唯一的列FID BEGIN SELECT COU ...

  7. 转载——JavaScript学习笔记:取数组中最大值和最小值

    转载自:http://www.w3cplus.com/javascript/calculate-the-max-min-value-from-an-array.html. 取数组中最大值 可以先把思路 ...

  8. JavaScript学习:取数组中最大值和最小值

    在实际业务中有的时候要取出数组中的最大值或最小值.但在数组中并没有提供arr.max()和arr.min()这样的方法.那么是不是可以通过别的方式实现类似这样的方法呢?那么今天我们就来整理取出数组中最 ...

  9. oracle 分组取第一行数据 ,查询sql语句

    oracle  分组取第一行数据 SELECT * FROM ( SELECT ROW_NUMBER() OVER(PARTITION BY x ORDER BY y DESC) rn, t.* FR ...

随机推荐

  1. 10月30日上午MySQL数据库的修改(从网页上实现对数据库的更改)

    从网页页面上对数据库进行更改,连接着之前做的增加.删除.查询. 1.先做一个修改页面 <body> <!--这个页面需要让用户看到一些数据,所以不是一个纯php页面,页面效果和增加页 ...

  2. Fedora 23安装 NS2 (network simulator 2)

    1 实验环境 OS: Fedora 23 workstation 2 实验步骤 ( 参考了:http://www.isi.edu/nsnam/ns/ns-build.html) 本次实验的实验环境: ...

  3. Canvas绘制渐变

    1.绘制线性渐变 Canvas提供了用于创建线性渐变的函数createLinearGradient(x0,y0,x1,y1),坐标点(x0,y0)是起点 ,(x1,y1)是终点 创建一个渐变色 var ...

  4. [Head First设计模式]策略模式

    系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...

  5. css浏览器兼容问题

    https://www.douban.com/group/topic/4629864/

  6. UI第十二节

    - (void)viewDidLoad {    [super viewDidLoad];        UIButton *btn = [UIButton buttonWithType:UIButt ...

  7. cf126b(kmp好题)

    http://codeforces.com/contest/126/problem/B #include<bits/stdc++.h> using namespace std; const ...

  8. PhpStorm 9.03 集成 开源中国(oschina.net)的Git项目,提交SVN时注意事项

    第一步:配置 git.exe File -> Default Settings -> Version Control -> Git -> Path go Git executa ...

  9. IntelliJ IDEA 14.x 快捷键/个性化设置

    常用快捷键设置(设置成跟Eclipse差不多) 按照路径:File -> Settings -> Appearance & Behavior -> Keymap -> ...

  10. Linux C 文件输入输出函数 fopen()、getc()/fgetc()、putc()/fputc()、fclose()、fprintf()、fscanf()、fgets()、fputs()、fseek()、ftell()、fgetpos()、fsetpos() 详解

      fopen(打开文件) 定义函数 FILE * fopen(const char * path,const char * mode); 函数说明 参数path字符串包含欲打开的文件路径及文件名,参 ...