zoukankan      html  css  js  c++  java
  • oracle分析函数中的开窗函数

    分析函数中的开窗函数
     
    --分析函数和聚合函数的区别
    ----普通的聚合函数用group by分组,每个分组返回一个统计值,
    ----分析函数采用partition by分组,并且每组每行都可以返回一个统计值。
     
    --分析函数语法结构
    FUNCTION_NAME(<参数>,…)
    OVER ( <PARTITION BY 表达式,…>
           <ORDER BY 表达式 <ASC DESC>
           <NULLS FIRST NULLS LAST>>
           <WINDOWING子句> )
     
    --PARTITION子句 ORDER BY子句 WINDOWING子句 缺省时相当于RANGE  UNBOUNDED PRECEDING。
     
    分析函数带有一个开窗函数over(),包含三个分析子句:
    分组(partition by)
    排序(order by)
    窗口(rows)
     
    数据用例:
    create table earnings -- 打工赚钱表
    (
        earnmonth varchar2(6), -- 打工月份
        area varchar2(20), -- 打工地区
        sno varchar2(10), -- 打工者编号
        sname varchar2(20), -- 打工者姓名
        times int, -- 本月打工次数
        singleincome number(10,2), -- 每次赚多少钱
        personincome number(10,2) -- 当月总收入
    )
    insert into earnings values('200912','北平','511601','大魁',11,30,11*30);  
    insert into earnings values('200912','北平','511602','大凯',8,25,8*25);  
    insert into earnings values('200912','北平','511603','小东',30,6.25,30*6.25);  
    insert into earnings values('200912','北平','511604','大亮',16,8.25,16*8.25);  
    insert into earnings values('200912','北平','511605','贱敬',30,11,30*11);  
    insert into earnings values('200912','金陵','511301','小玉',15,12.25,15*12.25);  
    insert into earnings values('200912','金陵','511302','小凡',27,16.67,27*16.67);  
    insert into earnings values('200912','金陵','511303','小妮',7,33.33,7*33.33);  
    insert into earnings values('200912','金陵','511304','小俐',0,18,0);  
    insert into earnings values('200912','金陵','511305','雪儿',11,9.88,11*9.88);  
    insert into earnings values('201001','北平','511601','大魁',0,30,0);  
    insert into earnings values('201001','北平','511602','大凯',14,25,14*25);  
    insert into earnings values('201001','北平','511603','小东',19,6.25,19*6.25);  
    insert into earnings values('201001','北平','511604','大亮',7,8.25,7*8.25);  
    insert into earnings values('201001','北平','511605','贱敬',21,11,21*11);  
    insert into earnings values('201001','金陵','511301','小玉',6,12.25,6*12.25);  
    insert into earnings values('201001','金陵','511302','小凡',17,16.67,17*16.67);  
    insert into earnings values('201001','金陵','511303','小妮',27,33.33,27*33.33);  
    insert into earnings values('201001','金陵','511304','小俐',16,18,16*18);  
    insert into earnings values('201001','金陵','511305','雪儿',11,9.88,11*9.88);  
    commit;
     
     
    1.连续求和分析函数 sum(…) over(…)
    功能:发现,如果分组或排序中包含sum()中的关键字段,就会变成连续求和,否则就是求总和
    用法:
    --sum(sal) over (partition by deptno order by ename) 按部门“连续”求总和
    select earnmonth 月份,area 地区,sname 打工者,   personincome 收入,
        sum(personincome) over (partition by earnmonth,area order by  personincome ) 连续收入  
    from earnings;
     
    --sum(sal) over (partition by deptno)
    select earnmonth 月份,area 地区,sname 打工者,   personincome 收入,
        sum(personincome) over (partition by earnmonth,area  ) 按月份地区求总和  
    from earnings;
     
    --sum(sal) over (order by deptno,ename)
    select earnmonth 月份,area 地区,sname 打工者,   personincome 收入,
        sum(personincome) over (order by earnmonth,area  ) 按月份地区求总和  
    from earnings;
     
    --sum(sal) over () 不按部门,求所有员工总和,效果等同于sum(sal)。
    select earnmonth 月份,area 地区,sname 打工者,   personincome 收入,
        sum(personincome) over () 总和  
    from earnings;
     
    2.连续求最大分析函数 max(…) over(…)
    用法:
    --max(sal) over (partition by deptno order by ename)
    select earnmonth 月份,area 地区,sname 打工者,   personincome 收入,
        max(personincome) over (partition by earnmonth,area) 分组取最大收入  
    from earnings;
     
    --max(sal) over (order by deptno,ename)
    select earnmonth 月份,area 地区,sname 打工者,   personincome 收入,
        max(personincome) over (order by earnmonth,area  ) 按月份地区求总和  
    from earnings;
     
    --max(sal) over () 不按部门,求所有员工总和,效果等同于sum(sal)。
    select earnmonth 月份,area 地区,sname 打工者,   personincome 收入,
        max(personincome) over () 求最大  
    from earnings;
     
     
    3.连续求最小分析函数 min(…) over(…)
    用法:
    --max(sal) over (partition by deptno order by ename)
    select earnmonth 月份,area 地区,sname 打工者,   personincome 收入,
        max(personincome) over (partition by earnmonth,area) 分组取最大收入  
    from earnings;
     
    --max(sal) over (order by deptno,ename)
    select earnmonth 月份,area 地区,sname 打工者,   personincome 收入,
        max(personincome) over (order by earnmonth,area  ) 按月份地区求总和  
    from earnings;
     
    --max(sal) over () 不按部门,求所有员工总和,效果等同于sum(sal)。
    select earnmonth 月份,area 地区,sname 打工者,   personincome 收入,
        max(personincome) over () 求最大  
    from earnings;
     
    4.连续求平均分析函数 avg(…) over(…)
    用法:
    --max(sal) over (partition by deptno order by ename)
    select earnmonth 月份,area 地区,sname 打工者,   personincome 收入,
        max(personincome) over (partition by earnmonth,area) 分组取最大收入  
    from earnings;
     
    --max(sal) over (order by deptno,ename)
    select earnmonth 月份,area 地区,sname 打工者,   personincome 收入,
        max(personincome) over (order by earnmonth,area  ) 按月份地区求总和  
    from earnings;
     
    --max(sal) over () 不按部门,求所有员工总和,效果等同于sum(sal)。
    select earnmonth 月份,area 地区,sname 打工者,   personincome 收入,
        max(personincome) over () 求最大  
    from earnings;
     
     
    --分析函数RANK 和 dense_rank 主要的功能是计算一组数值中的排序值。
     
    5.rank() over开窗函数
    用法:
    select earnmonth 月份,area 地区,sname 打工者, personincome 收入,   
        rank() over (partition by earnmonth,area order by  personincome desc) 排名  
    from earnings order by 排名  ;
     
     
    --dense_rank在并列关系是,相关等级不会跳过。rank则跳过。
    rank()中2个并列第一,接下来就是第三名,第二名被跳过了;
    --dense_rank()是连续排序,有两个第一名时仍然跟着第二名。
     
    6.dense_rank () over开窗函数
    用法:
    select earnmonth 月份,area 地区,sname 打工者, personincome 收入,   
        dense_rank() over (partition by earnmonth,area order by  personincome desc) 排名  
    from earnings;
     
    --表示根据earnmonth,area分组,在分组内部根据 personincome排序,
    --而这个值就表示每组内部排序后的顺序编号(组内连续的唯一的)
     
    7.row_number() over开窗函数 返回的主要是“行”的信息,并没有排名.
    功能:用于取前几名,或者最后几名等
    用法:
    select earnmonth 月份,area 地区,sname 打工者, personincome 收入,   
        row_number() over (partition by earnmonth,area order by  personincome desc) 排名  
    from earnings;
     
     
     
    8.lag和lead函数是偏移量函数,可以查出一个字段的上一个值或者下一个值,配合over来使用
    功能:
        lead函数,这个函数是向上偏移:LEAD(EXP_STR,OFFSET,DEFVAL) OVER()  
        lag函数是向下偏移一位:LAG(EXP_STR,OFFSET,DEFVAL) OVER()  
     
        EXP_STR要取的列  
        OFFSET取偏移后的第几行数据  
        DEFVAL:没有符合条件的默认值
    用法:
    SELECT T.ID
         ,LAG(T.NAME) OVER(ORDER BY ID) MIN_V_01
         ,LAG(T.NAME,1,0) OVER(ORDER BY ID) MAX_V
         ,T.NAME
         ,LEAD(T.NAME,1,0) OVER(ORDER BY ID) MIN_V   
    FROM (
        SELECT 1 ID ,'1AA' NAME FROM DUAL
        UNION ALL
        SELECT 2 ,'2AA' FROM DUAL
        UNION ALL
        SELECT 3 ,'3AA' FROM DUAL
        UNION ALL
        SELECT 4 ,'4AA' FROM DUAL
        UNION ALL
        SELECT 5 ,'5AA' FROM DUAL
        UNION ALL
        SELECT 6 ,'6AA' FROM DUAL) T;
     
     
     
     
  • 相关阅读:
    做了好几年的程序员,才发现自己天天都在用设计模式!
    先搞清楚这些问题,简历上再写你熟悉Java!
    Java中实现多线程继承Thread类与实现Runnable接口的区别
    JAVA中实现多线程的四种方式
    JDK和Cglib动态代理
    Java中选择排序,冒泡排序,插入排序,快速排序
    java死锁详解
    github常用命令
    字符串之StringBuffer 与 StringBuilder的对比
    基础数据类型之AbstractStringBuilder
  • 原文地址:https://www.cnblogs.com/hcy-zyy/p/14782680.html
Copyright © 2011-2022 走看看