一、分析函数

  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. T-sql 行转列,数据库查询分页

    1 USE [APS_Future_FT] 2 GO 3 /****** Object: StoredProcedure [dbo].[A_CrudePrice] Script Date: 2013/ ...

  2. 活动a 使用 启动为结果 方法 启动 活动 b, b什么都不做 并返回给a,a中的 在活动结果时候 回调 是否被执行?

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 活动a 使用 启动为结果 方法 启动 活动 b, b什么都不做 并返回给a,a中的 在活 ...

  3. codeforce 429D. Tricky Function (思维暴力过)

    题目描述 Iahub and Sorin are the best competitive programmers in their town. However, they can't both qu ...

  4. linux 环境下git 命令小结

    转载自:http://blog.chinaunix.net/uid-28241959-id-3880025.html 本地建立仓库 先创建个文件夹,仓库的地点: mkdir cangkumkdir C ...

  5. linux查看端口被哪个服务占用的命令

    netstat -tunpl | grep 6379

  6. springboot-application.properties可配置属性总结 (datasource 和 JPA)

    ########################################## ###datasource ########################################## ...

  7. 【spring cloud】spring cloud 使用feign调用,1.fallback熔断器不起作用,2.启动报错Caused by: java.lang.ClassNotFoundException: com.netflix.hystrix.contrib.javanica.aop.aspectj.Hystri解决

    示例GitHub源码地址:https://github.com/AngelSXD/springcloud 1.首先使用feign调用,需要配置熔断器 2.配置熔断器需要将熔断器注入Bean,熔断器类上 ...

  8. 使用WCF测试客户端 z

    http://blog.csdn.net/u013036274/article/details/50570989 [是什么] WCF测试客户端(WCF Test Client)是一个用来测试WCF服务 ...

  9. mongodb的分布式集群(2、副本集)

    概述        副本集是主从复制的一种,是一种自带故障转移功能的主从复制.攻克了上述主从复制的缺点.实现主server发生问题后.不需人为介入.系统自己主动从新选举一个新的主server的功能. ...

  10. UBUNTU 14.04 INSTALL nsenter

    cd /tmp; curl https://www.kernel.org/pub/linux/utils/util-linux/v2.25/util-linux-2.25.tar.gz | tar - ...