[Oracle]高效的SQL语句之分析函数(三)--row_number() /rank()/dense_rank()

 

有些时候我们希望得到指定数据中的前n列,示例如下:

得到每个部门薪水最高的三个雇员:

先创建示例表

create   table  emp
as
select   *   from  scott.emp;

alter   table  emp
add   constraint  emp_pk
primary   key (empno);

create   table  dept
as
select   *   from  scott.dept;

alter   table  dept
add   constraint  dept_pk
primary   key (deptno);

先看一下row_number() /rank()/dense_rank()三个函数之间的区别

  select  emp.deptno,emp.sal,emp.empno,row_number()  over  (partition  by  deptno  order   by  sal  desc ) row_number,   -- 1,2,3
  rank()  over  (partition  by  deptno  order   by  sal  desc ) rank,  -- 1,1,3
  dense_rank()  over  (partition  by  deptno  order   by  sal  desc ) dense_rank  from  emp  -- 1,1,2

结果如下:

10      5000.00      7839      1      1      1
10      2450.00      7782      2      2      2
10      1300.00      7934      3      3      3
20      3000.00      7788      1      1      1
20      3000.00      7902      2      1      1
20      2975.00      7566      3      3      2
20      1100.00      7876      4      4      3
20      800.00      7369      5      5      4
30      2850.00      7698      1      1      1
30      1600.00      7499      2      2      2

取每个部门的薪水前三位雇员:

select  t.deptno,t.rank,t.sal  from
 (
 
select  emp. * ,row_number()  over  (partition  by  deptno  order   by  sal  desc ) row_number,   -- 1,2,3
  rank()  over  (partition  by  deptno  order   by  sal  desc ) rank,  -- 1,1,3
  dense_rank()  over  (partition  by  deptno  order   by  sal  desc ) dense_rank  from  emp  -- 1,1,2
 ) t
where  t.rank <= 3

结果如下:

10      1      5000.00
10      2      2450.00
10      3      1300.00
20      1      3000.00
20      1      3000.00
20      3      2975.00
30      1      2850.00
30      2      1600.00
30      3      1500.00

如果想输出成deptno  sal1   sal2   sal3这种类型的格式
步骤一(decode):

select  t.deptno,decode(row_number, 1 ,sal) sal1,decode(row_number, 2 ,sal) sal2,decode(row_number, 3 ,sal) sal3  from
 (
 
select  emp. * ,row_number()  over  (partition  by  deptno  order   by  sal  desc ) row_number,   -- 1,2,3
  rank()  over  (partition  by  deptno  order   by  sal  desc ) rank,  -- 1,1,3
  dense_rank()  over  (partition  by  deptno  order   by  sal  desc ) dense_rank  from  emp  -- 1,1,2
 ) t
where  t.rank <= 3

结果如下:

10      5000         
10                    2450     
10                              1300
20      3000         
20                    3000     
20                                2975
30      2850         
30                   1600     
30                              1500

步骤二(使用聚合函数去除null,得到最终结果):

select  t.deptno, max (decode(row_number, 1 ,sal)) sal1, max (decode(row_number, 2 ,sal)) sal2, max (decode(row_number, 3 ,sal)) sal3  from
 (
 
select  emp. * ,row_number()  over  (partition  by  deptno  order   by  sal  desc ) row_number,   -- 1,2,3
  rank()  over  (partition  by  deptno  order   by  sal  desc ) rank,  -- 1,1,3
  dense_rank()  over  (partition  by  deptno  order   by  sal  desc ) dense_rank  from  emp  -- 1,1,2
 ) t
where  t.rank <= 3
group   by  t.deptno 

结果如下:

10      5000      2450      1300
20      3000      3000      2975
30      2850      1600      1500

 

 

 

 

 

 

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值