一、分析函数

  1、分析函数
  分析函数是Oracle专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组然后计算基于组的某种统计值,并且每一组的每一行都可以返回一个统计值。

  2、分析函数和聚合函数的区别
  普通的聚合函数用group by分组,每个分组返回一个统计值,而分析函数采用partition by分组,并且每组每行都可以返回一个统计值。

3、分析函数的形式
  分析函数带有一个开窗函数over(),包含分析子句 。

  分析子句又由下面三部分组成:
  partition by :分组子句,表示分析函数的计算范围,不同的组互不相干;
  ORDER BY: 排序子句,表示分组后,组内的排序方式;
  ROWS/RANGE:窗口子句,是在分组(PARTITION BY)后,组内的子分组(也称窗口),此时分析函数的计算范围窗口,而不是PARTITON。窗口有两种,ROWS和RANGE;

  使用形式如下:

OVER(PARTITION BY xxx PORDER BY yyy ROWS BETWEEN rowStart AND rowEnd)

  注:窗口子句在这里我只说rows方式的窗口,range方式和滑动窗口也不提。

二、OVER() 函数

  1、sql 查询语句的 order by 和 OVER() 函数中的 ORDER BY 的执行顺序
  分析函数是在整个sql查询结束后(sql语句中的order by的执行比较特殊)再进行的操作, 也就是说sql语句中的order by也会影响分析函数的执行结果:

  [1] 两者一致:如果sql语句中的order by满足分析函数分析时要求的排序,那么sql语句中的排序将先执行,分析函数在分析时就不必再排序;
  [2] 两者不一致:如果sql语句中的order by不满足分析函数分析时要求的排序,那么sql语句中的排序将最后在分析函数分析结束后执行排序。

  2、分析函数中的分组/排序/窗口
      分析函数包含三个分析子句:分组(partition by), 排序(order by), 窗口(rows/range)
      窗口就是分析函数分析时要处理的数据范围,就拿sum来说,它是sum窗口中的记录而不是整个分组中的记录,因此我们在想得到某个栏位的累计值时,我们需要把窗口指定到该分组中的第一行数据到当前行, 如果你指定该窗口从该分组中的第一行到最后一行,那么该组中的每一个sum值都会一样,即整个组的总和。

  [A] range是逻辑窗口(值):是指定当前行对应值的范围取值,列数不固定,只要行值在范围内,对应列都包含在内。

  如:SUM(id) OVER ( ORDER BY id RANGE BETWEEN 1 PRECEING AND 2 FOLLOWING ),分析:
  当id=1时,是 1-1<=id<=1+2 的所有id值求和,即sum=1+1+3=5(取id为1,1,3);
  当id=3时,是3-1<=id<=3+2 的所有id值求和,即sum=3(取id为3);

  [B] rows是物理窗口(行):即根据order by 子句排序后,取的前N行及后N行的数据计算(与当前行的值无关,只与排序后的行号相关),

  如:SUM(id) OVER ( ORDER BY id ROWS BETWEEN 1 PRECEING AND 2 FOLLOWING ),是取前1行到后2行的数据求和,分析:
  当id=1时,前一行没数,,后二行是第3行,就是1到3行;
  当id=3时,前一行是第2行,后二行是第5行,就是2到5行;

  2.1 带有窗口子句

  窗口子句,是在分组(PARTITION BY)后,组内的子分组(也称窗口),此时分析函数的计算范围窗口,而不是PARTITON。窗口有两种,ROWS和RANGE。若使用窗口子句,必须有ORDER BY 子句。
  窗口子句中经常用到指定行:第一行(unbounded preceding),当前行(current row),最后一行(unbounded following),以及前num1行(num1 preceding )和 后num2行(num2 following)。
  窗口子句不能单独出现,必须有order by子句时才能出现,如:

last_value(sal)
over(partition by deptno
order by sal
rows between unbounded preceding and unbounded following)

  以上示例指定窗口为整个分组。而出现order by子句的时候,不一定要有窗口子句,但效果会很不一样,此时的窗口默认是当前组的第一行到当前行!

  2.2 当省略窗口子句时:
  [1] 如果存在order by则默认的窗口是unbounded preceding and current row  --当前组的第一行到当前行
  [2] 如果同时省略order by则默认的窗口是unbounded preceding and unbounded following  --整个组

  2.3 如果省略分组,则把全部记录当成一个组:
  [1] 如果存在order by则默认窗口是unbounded preceding and current row   --当前组的第一行到当前行

  [2]如果这时省略order by则窗口默认为unbounded preceding and unbounded following  --整个组

三、常用分析函数

  1、排名函数

  函数为每条记录产生一个从1开始至n的自然数,n的值可能小于等于记录的总数。这3个函数的唯一区别在于当碰到相同数据时的排名策略。

  1.1 row_number() over()

  row_number()返回一个唯一的值,当碰到相同数据时,排名按照记录集中记录的顺序依次递增。
  1.2 rank() over()

  rank()返回一个唯一的值,当碰到相同的数据时,此时所有相同数据的排名是一样的,同时会在最后一条相同记录和下一条不同记录的排名之间空出排名。
  1.3 dense_rank() over()

  dense_rank()返回一个唯一的值,当碰到相同数据时,此时所有相同数据的排名都是一样的,同时会在最后一条相同记录和下一条不同记录的排名之间紧邻递增。

  2、聚合函数

  2.1 count() over()
  2.2 max() over()
  2.3 min() over()
  2.4 sum() over()
  2.5 avg() over()

  3、 求最值对应的其他属性
  3.1 first_value() over():第一个值
  3.2 last_value() over():最后一个值

  4、求之前或之后的第N行

  注:行比较分析函数lead和lag无window(窗口)子句。

  lag(arg1,arg2,arg3) 和 lead(arg1,arg2,arg3) 可以在一次查询中取出同一字段的前n行的数据和后n行的值。这种操作可以使用对相同表的表连接来实现,不过使用lag和lead有更高的效率。
  [1] arg1:参数是列名,
  [2] arg2:参数是偏移的offset,
  [3] arg3:参数是超出记录窗口时的默认值。
  4.1 lag() over()

    lag()函数向下偏移。
  4.2 lead() over()

    lead()函数是向上偏移。

  举例如下:
  select *  from kkk;                                         
                                                                 
        ID NAME                                                  
---------- --------------------                                  
         1 1name                                                 
         2 2name                                                 
         3 3name                                                 
         4 4name                                                 
         5 5name                                                 
  select id,name,lag(name,1,0) over(order by id) from kkk;
                                                                 
        ID NAME                 LAG(NAME,1,0)OVER(ORDERBYID)     
---------- -------------------- ----------------------------     
         1 1name                0                                
         2 2name                1name                            
         3 3name                2name                            
         4 4name                3name                            
         5 5name                4name

  select id,name,lead(name,1,0) over(order by id) from kkk;
                                                                 
        ID NAME                 LEAD(NAME,1,0)OVER(ORDERBYID)    
---------- -------------------- -----------------------------    
         1 1name                2name                            
         2 2name                3name                            
         3 3name                4name                            
         4 4name                5name                            
         5 5name                0

  select id,name,lead(name,2,0) over(order by id) from kkk;                                                                                                              
        ID NAME                 LEAD(NAME,2,0)OVER(ORDERBYID)    
---------- -------------------- -----------------------------    
         1 1name                3name                            
         2 2name                4name                            
         3 3name                5name                            
         4 4name                0                                
         5 5name                0 
  select id,name,lead(name,1,'linjiqin') over(order by id) from kkk;                                 
                                                                                 
        ID NAME                 LEAD(NAME,1,'ALSDFJLASDJFSAF')                   
---------- -------------------- ------------------------------                   
         1 1name                2name                                            
         2 2name                3name                                            
         3 3name                4name                                            
         4 4name                5name                                            
         5 5name                linjiqin

---------------------------------------------------------------------------------------

  5、排列组合函数,只能用在 GROUP BY 后边

  5.1 group by rollup(a, b, c):
  
首先会对(a、b、c)进行group by,
  然后再对(a、b)进行group by,
  其后再对(a)进行group by,
  最后对全表进行汇总操作。

  5.2 group by cube(a, b, c):
  首先会对(a、b、c)进行group by,
  然后依次是(a、b),(a、c),(a),(b、c),(b),(c),
  最后对全表进行汇总操作。

  5.3 示例如下:

  5.3.1 普通 group by 分组
  sql> select owner, index_type, status, count(*) from t where owner like 'SY%' group by owner, index_type, status;

  

  5.3.2 GROUP BY ROLLUP(A, B, C):
  首先会对(A、B、C)进行GROUP BY,
  然后再对(A、B)进行GROUP BY,
  其后再对(A)进行GROUP BY,
  最后对全表进行汇总操作。
  select owner, index_type, status, count(*) from t where owner like 'SY%' group by ROLLUP(owner, index_type, status);

  

  5.3.3 GROUP BY CUBE(A, B, C):
  首先会对(A、B、C)进行GROUP BY,
  然后依次是(A、B),(A、C),(A),(B、C),(B),(C),
  最后对全表进行汇总操作。

  select owner, index_type, status, count(*) from t where owner like 'SY%' group by cube(owner, index_type, status);

  

Oracle 之 分析函数的更多相关文章

  1. oracle的分析函数over 及开窗函数

    转:http://www.2cto.com/database/201310/249722.html oracle的分析函数over 及开窗函数   一:分析函数over   Oracle从8.1.6开 ...

  2. Oracle 10gR2分析函数

    Oracle 10gR2分析函数汇总 (Translated By caizhuoyi 2008‐9‐19) 说明:  1. 原文中底色为黄的部分翻译存在商榷之处,请大家踊跃提意见:  2. 原文中淡 ...

  3. 超级牛皮的oracle的分析函数over(Partition by...) 及开窗函数 (转)

    http://zonghl8006.blog.163.com/blog/static/4528311520083995931317/ over(Partition by...) 一个超级牛皮的ORAC ...

  4. 超级牛皮的oracle的分析函数over(Partition by...) 及开窗函数

    over(Partition by...) 一个超级牛皮的ORACLE特有函数. 天天都用ORACLE,用了快2年了.最近才接触到这个功能强大而灵活的函数.真实惭愧啊! oracle的分析函数over ...

  5. oracle的分析函数over(Partition by...) 及开窗函数

        over(Partition by...) 一个超级牛皮的ORACLE特有函数. oracle的分析函数over 及开窗函数一:分析函数overOracle从8.1.6开始提供分析函数,分析函 ...

  6. Oracle的分析函数

    Oracle的分析函数row_number(),rank(),dense_rank()的用法与区别 比如查询工资排名第7的员工信息,可以用分析函数来做. --查询工资排名第7的员工信息select * ...

  7. 分组函数group by和Oracle中分析函数partition by的用法以及区别

    1.分组函数group by和Oracle中分析函数partition by的用法以及区别 2.开窗函数.

  8. Oracle排序分析函数

    在Oracle自拓展SQL功能中,分析函数(Analytical Function)是非常强大的工具. 本篇我们介绍几个Oracle典型的排序分析函数,来帮助我们解决实际问题. 1.从rownum谈起 ...

  9. Oracle所有分析函数<转>

    Oracle分析函数——函数列表 SUM        :该函数计算组中表达式的累积和 MIN        :在一个组中的数据窗口中查找表达式的最小值 MAX        :在一个组中的数据窗口中 ...

  10. oracle之分析函数解析及其应用场景

    ORACLE 分析函数FIRST_VALUE,LAST_VALUE用法sum overavg over first_value overlast_value over...聚合函数结合over就是分析 ...

随机推荐

  1. Opencv学习笔记2:图像模糊作用和方法

    一.意义和作用: 图像的模糊处理就是将图片处理的更加模糊,如下图,左侧是原图,右侧是经过处理之后的图片. 从主观意愿上说,我们希望看到清晰的图像,而不是模糊的图像.所以很多时候我们听说还有一种专门进行 ...

  2. 数据准备<1>:数据质量检查-理论篇

    数据行业有一句很经典的话--"垃圾进,垃圾出"(Garbage in, Garbage out, GIGO),意思就是,如果使用的基础数据有问题,那基于这些数据得到的任何产出都是没 ...

  3. 网络流24题之最长k可重线段集问题

    对于每个线段拆成两个点,如同之前一样建图,由于可能出现垂直于x轴的 所以建图由i指向i~ 继续最小费用最大流 By:大奕哥 #include<bits/stdc++.h> using na ...

  4. [CodeForces-440D]Berland Federalization

    题目大意: 给你一棵树,你可以删掉一些边,使得分除去的子树中至少有一棵大小为k. 问最少删去多少边,以及删边的具体方案. 思路: 树形DP. f[i][j]表示以i为根,子树中去掉j个点最少要删边的数 ...

  5. 【BZOJ】2002: [Hnoi2010]Bounce 弹飞绵羊

    2002: [Hnoi2010]Bounce 弹飞绵羊 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 14802  Solved: 7507[Subm ...

  6. 《深入理解Spark-核心思想与源码分析》(六)第六章计算引擎

    RDD是Spark对各类数据计算模型的统一抽象,被用于迭代计算过程以及任务输出结果的缓存读写. 在所有MapReduce框架中,shuffle是连接map任务和reduce任务的桥梁.shuffle性 ...

  7. 实用小工具 -- 国家地区IP段范围查询工具

    如果想限制某个国家地区IP段访问,这几个查询工具就很有用了. 可以查询各个国家IP段范围,并且是持续更新的,使用方便. 当然,除此之外,你还可以通过APNIC.ARIN.RIPE这些官方IP分配机构查 ...

  8. POJ 1293 - Duty Free Shop 01背包记录所选物品

    裸的01背包.dp[x]只要是bool型记录当前空间是否可用.. 而为了找到用了哪些物品..dp[x]设置为int型..进行记录.. Program: #include<iostream> ...

  9. MySQL系列:innodb源码分析之内存管理

    http://blog.csdn.net/yuanrxdu/article/details/40985363 http://book.2cto.com/201402/40307.html 从MySQL ...

  10. Integrate SharePoint 2013 with Team Foundation Server 2012

    Now that SharePoint 2013 is out I want to make sure that I can integrate SharePoint 2013 with Team F ...