转载自:http://www.2cto.com/database/201310/249722.html

oracle的分析函数over(Partition by...)
 
Sql代码  
    over(Partition by...) 一个超级牛皮的ORACLE特有函数。  
  
最近工作中才接触到这个功能强大而灵活的函数。  
  
oracle的分析函数over 及开窗函数  
一:分析函数over  
Oracle从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是  
对于每个组返回多行,而聚合函数对于每个组只返回一行。   
下面通过几个例子来说明其应用。  
1:统计某商店的营业额。         
     date       sale 
     1           20 
     2           15 
     3           14 
     4           18 
     5           30 
    规则:按天统计:每天都统计前面几天的总额 
    得到的结果: 
    DATE   SALE       SUM 
    ----- -------- ------ 
    1      20        20           --1天            
    2      15        35           --1天+2天            
    3      14        49           --1天+2天+3天            
    4      18        67            .           
    5      30        97            . 
        
2:统计各班成绩第一名的同学信息 
    NAME   CLASS S                          
    ----- ----- ----------------------  
    fda    1      80                      
    ffd    1      78                      
    dss    1      95                      
    cfe    2      74                      
    gds    2      92                      
    gf     3      99                      
    ddd    3      99                      
    adf    3      45                      
    asdf   3      55                      
    3dd    3      78               
      
    通过:    
    -- 
    select * from                                                                        
    (                                                                             
    select name,class,s,rank()over(partition by class order by s desc) mm from t2 
    )                                                                             
    where mm=1  
    -- 
    得到结果: 
    NAME   CLASS S                       MM                                                                                         
    ----- ----- ---------------------- ----------------------  
    dss    1      95                      1                       
    gds    2      92                      1                       
    gf     3      99                      1                       
    ddd    3      99                      1           
      
    注意: 
    1.在求第一名成绩的时候,不能用row_number(),因为如果同班有两个并列第一,row_number()只返回一个结果           
    2.rank()和dense_rank()的区别是: 
      --rank()是跳跃排序,有两个第二名时接下来就是第四名 
      --dense_rank()l是连续排序,有两个第二名时仍然跟着第三名 
        
        
3.分类统计 (并显示信息) 
    A   B   C                       
    -- -- ----------------------  
    m   a   2                       
    n   a   3                       
    m   a   2                       
    n   b   2                       
    n   b   1                       
    x   b   3                       
    x   b   2                       
    x   b   4                       
    h   b   3  
   select a,c,sum(c)over(partition by a) from t2                 
   得到结果: 
   A   B   C        SUM(C)OVER(PARTITIONBYA)       
   -- -- ------- ------------------------  
   h   b   3        3                         
   m   a   2        4                         
   m   a   2        4                         
   n   a   3        6                         
   n   b   2        6                         
   n   b   1        6                         
   x   b   3        9                         
   x   b   2        9                         
   x   b   4        9                         
     
   如果用sumgroup by 则只能得到 
   A   SUM(C)                             
   -- ----------------------  
   h   3                       
   m   4                       
   n   6                       
   x   9                       
   无法得到B列值        
     
===== 
select * from test 
   
数据: 
A B C  
1 1 1  
1 2 2  
1 3 3  
2 2 5  
3 4 6  
   
   
---将B栏位值相同的对应的C 栏位值加总 
select a,b,c, SUM(C) OVER (PARTITION BY B) C_Sum 
from test 
   
A B C C_SUM  
1 1 1 1  
1 2 2 7  
2 2 5 7  
1 3 3 3  
3 4 6 6  
   
---如果不需要已某个栏位的值分割,那就要用 null 
   
eg: 就是将C的栏位值summary 放在每行后面 
   
select a,b,c, SUM(C) OVER (PARTITION BY null) C_Sum 
from test 
   
A B C C_SUM  
1 1 1 17  
1 2 2 17  
1 3 3 17  
2 2 5 17  
3 4 6 17 
   
求个人工资占部门工资的百分比  
   
SQL> select * from salary; 
   
NAME DEPT SAL 
---------- ---- ----- 
a 10 2000 
b 10 3000 
c 10 5000 
d 20 4000 
   
SQL> select name,dept,sal,sal*100/sum(sal) over(partition by dept) percent from salary; 
   
NAME DEPT SAL PERCENT 
---------- ---- ----- ---------- 
a 10 2000 20 
b 10 3000 30 
c 10 5000 50 
d 20 4000 100 
   
二:开窗函数            
      开窗函数指定了分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变化而变化,举例如下:  
1:      
   over(order by salary) 按照salary排序进行累计,order by是个默认的开窗函数 
   over(partition by deptno)按照部门分区 
2: 
  over(order by salary range between 5 preceding and 5 following) 
   每行对应的数据窗口是之前行幅度值不超过5,之后行幅度值不超过5 
   例如:对于以下列 
     aa 
     
     
     
     
     
     
     
     
     
     
      
   sum(aa)over(order by aa range between 2 preceding and 2 following) 
   得出的结果是 
            AA                       SUM 
            ---------------------- -------------------------------------------------------  
            1                       10                                                       
            2                       14                                                       
            2                       14                                                       
            2                       14                                                       
            3                       18                                                       
            4                       18                                                       
            5                       22                                                       
            6                       18                                                                 
            7                       22                                                                 
            9                       9                                                                  
                
   就是说,对于aa=5的一行 ,sum为   5-1<=aa<=5+2 的和 
   对于aa=2来说 ,sum=1+2+2+2+3+4=14     ; 
   又如 对于aa=9 ,9-1<=aa<=9+2 只有9一个数,所以sum=9    ; 
                 
3:其它: 
     over(order by salary rows between 2 preceding and 4 following) 
          每行对应的数据窗口是之前2行,之后4行  
4:下面三条语句等效:            
     over(order by salary rows between unbounded preceding and unbounded following) 
          每行对应的数据窗口是从第一行到最后一行,等效: 
     over(order by salary range between unbounded preceding and unbounded following) 
           等效 
     over(partition by null
   
常用的分析函数如下所列: 
   
row_number() over(partition by ... order by ...) 
rank() over(partition by ... order by ...) 
dense_rank() over(partition by ... order by ...) 
count() over(partition by ... order by ...) 
max() over(partition by ... order by ...) 
min() over(partition by ... order by ...) 
sum() over(partition by ... order by ...) 
avg() over(partition by ... order by ...) 
first_value() over(partition by ... order by ...) 
last_value() over(partition by ... order by ...) 
lag() over(partition by ... order by ...) 
lead() over(partition by ... order by ...) 
   
示例 
SQL> select type,qty from test; 
   
TYPE QTY 
---------- ---------- 
1 6 
2 9 
   
 SQL> select type,qty,to_char(row_number() over(partition by type order by qty))||'/'||to_char(count(*) over(partition by type)) as cnt2 from test; 
   
TYPE QTY CNT2  
---------- ---------- ------------ 
3 1/2 
1 6 2/2 
2 5 1/3 
7 2/3  
2 9 3/3 
   
 SQL> select * from test; 
---------- ------------------------------------------------- 
1 11111 
2 22222 
3 33333 
4 44444 
   
SQL> select t.id,mc,to_char(b.rn)||'/'||t.id)e 
2 from test t, 
 (select rownum rn from (select max(to_number(id)) mid from test) connect by rownum <=mid ))L 
4 where b.rn<=to_number(t.id) 
order by id 
   
ID MC TO_CHAR(B.RN)||'/'||T.ID 
--------- -------------------------------------------------- --------------------------------------------------- 
1 11111 1/1 
2 22222 1/2 
2 22222 2/2 
3 33333 1/3 
3 33333 2/3 
3 33333 3/3 
 44444 1/4 44444 2/4 
4 44444 3/4CNOUG4 44444 4/4 
   
10 rows selected 
   
*******************************************************************
 
关于partition by  
  
这些都是分析函数,好像是8.0以后才有的 row_number()和rownum差不多,功能更强一点(可以在各个分组内从1开时排序) rank()是跳跃排序,有两个第二名时接下来就是第四名(同样是在各个分组内) dense_rank()l是连续排序,有两个第二名时仍然跟着第三名。相比之下row_number是没有重复值的 lag(arg1,arg2,arg3): arg1是从其他行返回的表达式 arg2是希望检索的当前行分区的偏移量。是一个正的偏移量,时一个往回检索以前的行的数目。 arg3是在arg2表示的数目超出了分组的范围时返回的值。 
1. 
select deptno,row_number() over(partition by deptno order by sal) from emp order by deptno; 
2. 
select deptno,rank() over (partition by deptno order by sal) from emp order by deptno; 
3. 
select deptno,dense_rank() over(partition by deptno order by sal) from emp order by deptno; 
4. 
select deptno,ename,sal,lag(ename,1,null) over(partition by deptno order by ename) from emp ord er by deptno; 
5. 
select deptno,ename,sal,lag(ename,2,'example') over(partition by deptno order by ename) from em p 
order by deptno; 
6. 
select deptno, sal,sum(sal) over(partition by deptno) from emp;--每行记录后都有总计值  select deptno, sum(sal) from emp group by deptno; 
7. 求每个部门的平均工资以及每个人与所在部门的工资差额 
   
select deptno,ename,sal , 
     round(avg(sal) over(partition by deptno)) as dept_avg_sal,  
     round(sal-avg(sal) over(partition by deptno)) as dept_sal_diff 
from emp;
 
 

procedure的over(partition by ) function的更多相关文章

  1. [独孤九剑]Oracle知识点梳理(六)数据库常用对象之Procedure、function、Sequence

    本系列链接导航: [独孤九剑]Oracle知识点梳理(一)表空间.用户 [独孤九剑]Oracle知识点梳理(二)数据库的连接 [独孤九剑]Oracle知识点梳理(三)导入.导出 [独孤九剑]Oracl ...

  2. Delphi7中的函数与过程(Function and Procedure)

    1.锁住空间的位置,可以选择Edit--->Lock component ,也可以在窗体设计面板下面找到组件排版功能栏,第二排里面有个带锁的图标,表示组件可以被锁住.点击一下,组件的大小和位置就 ...

  3. [转]Dynamic SQL & Stored Procedure Usage in T-SQL

    转自:http://www.sqlusa.com/bestpractices/training/scripts/dynamicsql/ Dynamic SQL & Stored Procedu ...

  4. How to throw an error in MySql procedure?

    http://stackoverflow.com/questions/4862911/how-to-throw-an-error-in-mysql-procedure 9down votefavori ...

  5. Delphi 中的 procedure of object

    转载:http://www.cnblogs.com/ywangzi/archive/2012/08/28/2659811.html 总结:TMyEvent = procedure of object; ...

  6. 一个不简单的Procedure body例子

    create or replace package body CountBankData_20150617 is type cursorCommon is ref cursor; --游标类型 str ...

  7. MySQL与Oracle 差异比较之五存储过程&Function

    存储过程&Function 编号 类别 ORACLE MYSQL 注释 1 创建存储过程语句不同 create or replace procedure P_ADD_FAC(   id_fac ...

  8. Delphi 中的 procedure of object (类方法存在一个隐藏参数self),简单深刻 good

    其实要了解这些东西,适当的学些反汇编,WINDOWS内存管理机制,PE结构,看下李维的VCL架构剖析可以很好理解type TMyEvent = procedure of object;这是一种数据类型 ...

  9. 存储过程&Function

    存储过程&Function 编号 类别 ORACLE MYSQL 注释 1 创建存储过程语句不同 create or replace procedure P_ADD_FAC(   id_fac ...

随机推荐

  1. HDU-4690 EBCDIC 映射,模拟,沙茶

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4690 纯沙茶模拟题... //STATUS:C++_AC_93MS_228KB #include &l ...

  2. UI进阶 多线程

    一.多线程概述 程序.进程.线程 程序:由源代码生成的可执行应用.(例如:QQ.app) 进程:一个正在运行的程序可以看做一个进程.(例如:正在运行的QQ就是一个进程),进程拥有独立运行所需的全部资源 ...

  3. iOS开发-网络-合理封装请求接口

    概述 如今大多App都会与网络打交道,作为开发者,合理的对网络后台请求接口进行封装十分重要.本文要介绍的就是一种常见的采用回调函数(方法)的网络接口封装,也算的是一种构架吧. 这个构架主要的idea是 ...

  4. ModSecurity--web应用防火墙

    Introducing ModSecurity IIS 2.7.2 Stable Release ★★★★★ ★★★★ ★★★ ★★ ★   swiatFebruary 11, 20130 0 0 0 ...

  5. Codeforces Round #323 (Div. 2) C. GCD Table 暴力

    C. GCD Table Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/583/problem/C ...

  6. zookeeper使用场景【转】

    分布式网站架构后续:zookeeper技术浅析   Zookeeper是hadoop的一个子项目,虽然源自hadoop,但是我发现zookeeper脱离hadoop的范畴开发分布式框架的运用越来越多. ...

  7. [React] Higher Order Components (replaces Mixins)

    Higher order components will allow you to apply behaviors to multiple React components. So the idea ...

  8. android学习日记07--Canvas画布

    1.Canvas Canvas类主要实现了屏幕的绘制过程,其中包含了很多实用的方法,比如绘制一条路径.区域.贴图.画点.画线.渲染文本,当然Android官网提示大家很多方法有不同的重载版本,参数更灵 ...

  9. Chrome 扩展程序 CrxMouse 优化版 v3.0.1

    说明 CrxMouse 原版更新至 v2.7.8,跟进升级优化版至 v3.0.1. 改动说明: 1. 去除可能存在的后台数据上传隐患: 2. 解决鼠标右键拖动时的轨迹漂移问题. 3. 加入部分默认设置 ...

  10. node.js 针对不同的请求路径(url) 做出不同的响应

    边看这个边写的: http://wenku.baidu.com/link?url=C4yLe-TVH6060u_x4t34H3Ze8tjoL7HjJaKgH-TvHnEYl-T_gAMYwhmrCeM ...