数据库--oracle--分析函数OVER ()

准备工作: 
table:oracle用户scott下的emp表 ; 

一. 
Oracle 从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是 

  对于每个组返回多行,而聚合函数对于每个组只返回一行。 

exp: 
Sql代码   收藏代码
  1. select t.empno,t.ename,sum(t.sal) from emp t  

这样会报:ORA-00937:非单组分组函数; 
结论:聚合函数只能返回1行值。 
Sql代码   收藏代码
  1. select t.empno,t.ename,sum(t.sal)over() sum from emp t  

返回的结果: 
empnoenamesum
7369SMITH142781.99
7499ALLEN142781.99
7521WARD142781.99
7566JONES142781.99
7654MARTIN142781.99
7698BLAKE142781.99
7782CLARK142781.99
7788SCOTT142781.99
7839KING142781.99
7844TURNER142781.99
7876ADAMS142781.99
7900JAMES142781.99
7902FORD142781.99
7934MILLER142781.99

结论:这就是每个组返回多行。 

二. 
over()、over(order by...)与over(partition by...)之间的区别 
1.分析函数over()用在聚合函数(max(),sun()....)后面,可返回多行所有结果的聚合值; 
exp:如上; 

2.over(order by...)用在聚合函数(max(),sun()....)后面,可返回根据排序结果进行统计到当前行的聚合值(即“连续”统计); 
exp:
Sql代码   收藏代码
  1. select t.empno,  
  2.        t.deptno,  
  3.        t.ename,  
  4.        t.sal,  
  5.        sum(t.sal) over(order by t.ename) sum  
  6.   from emp t  

返回的结果: 
empnodeptnoename    sal      sum
787620ADAMS4646.114646.11
749930ALLEN8493.6613139.77
769830BLAKE15047.6928187.46
778210CLARK11823.8540011.31
790220FORD14935.9754947.28
790030JAMES4935.3659882.64
756620JONES15086.3074968.94
783910KING23841.1398810.07
765430MARTIN6526.80105336.87
793410MILLER6167.32111504.19
778820SCOTT12710.16124214.35
736920SMITH4089.17128303.52
784430TURNER7843.77136147.29
752130WARD6634.70142781.99

分析:第二行的sum=第一行里的sal+第二行里的sal; 
      第二行的sum=第一行里的sal+第二行里的sal+第三行里的sal; 
      ..... 
结论:返回值是根据排序后的结果,当前所在的行进行统计的。 

3.over(partition by...)用在聚合函数(max(),sun()....)后面,可根据pratition by里指定的某一列来统计聚合值。 
exp:
Sql代码   收藏代码
  1. select t.empno,  
  2.        t.deptno,  
  3.        t.ename,  
  4.        t.sal,  
  5.        sum(t.sal) over(partition by t.deptno) sum  
  6.   from emp t  


返回的结果: 
empnodeptno  ename    sal      sum
778210CLARK11823.8541832.3
783910KING23841.1341832.3
793410MILLER6167.3241832.3
736920SMITH4089.1751467.71
787620ADAMS4646.1151467.71
790220FORD14935.9751467.71
778820SCOTT12710.1651467.71
756620JONES15086.3051467.71
749930ALLEN8493.6649481.98
769830BLAKE15047.6949481.98
765430MARTIN6526.8049481.98
790030JAMES4935.3649481.98
784430TURNER7843.7749481.98
752130WARD6634.7049481.98

分析:每个sum的值都是把deptno相同的sal值进行求和。 
结论:根据pratition by里指定的某一列来统计聚合值。 

三.一个综合的例子: 
exp: 
question: 
按部门“连续”求总和; 
answer: 
Sql代码   收藏代码
  1. select t.empno,  
  2.        t.deptno,  
  3.        t.ename,  
  4.        t.sal,  
  5.        sum(t.sal) over(partition by t.deptno order by t.ename) sum  
  6.   from emp t  


返回的结果: 
empnodeptno  ename    sal      sum
778210CLARK11823.8511823.85
783910KING23841.1335664.98
793410MILLER6167.3241832.3
787620ADAMS4646.114646.11
790220FORD14935.9719582.08
756620JONES15086.3034668.38
778820SCOTT12710.1647378.54
736920SMITH4089.1751467.71
749930ALLEN8493.668493.66
769830BLAKE15047.6923541.35
790030JAMES4935.3628476.71
765430MARTIN6526.8035003.51
784430TURNER7843.7742847.28
752130WARD6634.7049481.98

分析:先根据partition by 进行分组,然后再根据order by 进行排序“连续”统计。 

四.一个实际的例子来说明over()分析函数在代码上能简化和提高效率。 
question: 
         查询出管理员工人数最多的人的名字和他管理的人的名字 
answer: 
1.普通的方法: 
Sql代码   收藏代码
  1. select d.ename 管理员工人数最多的人的名字, o.ename 他管理的人的名字  
  2.   from emp d, emp o  
  3.  where o.empno = d.mgr  
  4.    and d.empno in  
  5.        (select p.empno  
  6.           from emp p  
  7.          where p.empno in  
  8.                (select r.mgr  
  9.                   from (select e.mgr, count(e.mgr) c from emp e group by e.mgr) r  
  10.                  where r.c is  
  11.                        (select max(w.z)  
  12.                           from (select count(m.mgr) z from emp m group by m.mgr) w)))  

2.使用over()分析函数: 
Sql代码   收藏代码
  1. select e.ename 管理员工人数最多的人的名字, j.ename 他管理的人的名字  
  2.   from emp e, emp j  
  3.  where j.empno = e.mgr  
  4.    and e.empno in (select distinct (r.mgr)  
  5.                      from (select m.mgr,  
  6.                                   count(m.mgr) over(partition by m.mgr order by m.empno) t  
  7.                              from emp m) r  
  8.                     where r.t is (select max(y.h)  
  9.                                from (select count(p.mgr) over(partition by p.mgr order by p.empno) h  
  10.                                             from emp p) y))  

输出结果是一样的: 
管理员工人数最多的人的名字他管理的人的名字
BLAKEKING

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值