Oracle 10g 分析函数

  1. 分析函数
  2.   它是Oracle分析函数专门针对类似于"经营总额""找出一组中的百分之多少" 或"计算排名前几位"等问题设计的。
  3. 分析函数运行效率高,使用方便。
  4.   分析函数是基于一组行来计算的。这不同于聚集函数且广泛应用于OLAP环境中。
  5.   Oracle从8.1.6开始提供分析函数,分析函数用于计算基于组的某种聚合值,它和聚合函数的不同之处是
  6. 对于每个组返回多行,而聚合函数对于每个组只返回一行。 
  7. 语法:
  8. <analytic-function>(<argument>,<argument>,...)
  9. over(
  10.   <query-partition-clause>
  11.   <order-by-clause>
  12.   <windowing-clause>
  13. )
  14. 其中:
  15. 1 over是关键字,用于标识分析函数。
  16. 2 <analytic-function>是指定的分析函数的名字。Oracle分析函数很多。
  17. 3 <argument>为参数,分析函数可以选取0-3个参数。
  18. 4 分区子句<query-partition-clause>的格式为:
  19.   partition by<value_exp>[,value_expr]...
  20.   关键字partition by子句根据由分区表达式的条件逻辑地将单个结果集分成N组。这里的"分区partition""组group"
  21. 都是同义词。
  22. 5 排序子句order-by-clause指定数据是如何存在分区内的。其格式为:
  23.  order[siblings]by{expr|position|c_alias}[asc|desc][nulls first|nulls last]
  24. 其中:
  25. (1)asc|desc:指定了排列顺序。
  26. (2)nulls first|nulls last:指定了包含空值的返回行应出现在有序序列中的第一个或最后一个位置。
  27. 6窗口子句windowing-clause
  28.  给出一个固定的或变化的数据窗口方法,分析函数将对这些数据进行操作。在一组基于任意变化或固定的窗口中,
  29. 可用该子句让分析函数计算出它的值。
  30. 格式:
  31.  {rows|range}
  32.  {between
  33.   {unbounded preceding|current row |<value_expr>{preceding|following}
  34.  }and
  35.  {unbounded preceding|current row |<value_expr>{preceding|following}
  36.  }|{unbounded preceding|current row |<value_expr>{preceding|following
  37.  }}
  38. (1)rows|range:此关键字定义了一个window。
  39. (2)between...and...:为窗品指一个起点和终点。
  40. (3)unbounded preceding:指明窗口是从分区(partition)的第一行开始。
  41. (4)current row:指明窗口是从当前行开始。
  42. create table emp(
  43.  deptno varchar2(20),--部门编码
  44.  ename varchar2(20),--人名
  45.  sal number(10));--工资
  46. insert into emp values('10','andy1',2000);
  47. insert into emp values('10','andy2',3000);
  48. insert into emp values('10','andy3',2000);
  49. insert into emp values('20','leno1',4000);
  50. insert into emp values('20','leno2',8000);
  51. insert into emp values('20','leno3',6000);
  52. insert into emp values('30','jack1',5000);
  53. insert into emp values('30','jack2',6000);
  54. insert into emp values('30','jack3',7000);
  55. 1 连续求和
  56. select deptno,ename,sal,sum(sal) over(order by ename)  连续求和 from emp;
  57. DEPTNO               ENAME                        SAL       连续求和
  58. -------------------- -------------------- ----------- ----------
  59. 10                   andy1                       2000       2000
  60. 10                   andy2                       3000       5000
  61. 10                   andy3                       2000       7000
  62. 30                   jack1                       5000      12000
  63. 30                   jack2                       6000      18000
  64. 30                   jack3                       7000      25000
  65. 20                   leno1                       4000      29000
  66. 20                   leno2                       8000      37000
  67. 20                   leno3                       6000      43000
  68. 2 不连续求和
  69. select deptno,ename,sal,sum(sal) over()  不连续求和 from emp;
  70. DEPTNO               ENAME                        SAL      不连续求和
  71. -------------------- -------------------- ----------- ----------
  72. 10                   andy1                       2000      43000
  73. 10                   andy2                       3000      43000
  74. 10                   andy3                       2000      43000
  75. 20                   leno1                       4000      43000
  76. 20                   leno2                       8000      43000
  77. 20                   leno3                       6000      43000
  78. 30                   jack1                       5000      43000
  79. 30                   jack2                       6000      43000
  80. 30                   jack3                       7000      43000
  81. 3.
  82. select deptno,ename,sal,
  83. sum(sal) over(order by ename) 连续求和,
  84. sum(sal) over() 总和,
  85. 100*round(sal/sum(sal) over(),4) "份额(%)"
  86. from emp
  87. /
  88. DEPTNO               ENAME                        SAL       连续求和         总和      份额(%)
  89. -------------------- -------------------- ----------- ---------- ---------- ----------
  90. 10                   andy1                       2000       2000      43000       4.65
  91. 10                   andy2                       3000       5000      43000       6.98
  92. 10                   andy3                       2000       7000      43000       4.65
  93. 30                   jack1                       5000      12000      43000      11.63
  94. 30                   jack2                       6000      18000      43000      13.95
  95. 30                   jack3                       7000      25000      43000      16.28
  96. 20                   leno1                       4000      29000      43000        9.3
  97. 20                   leno2                       8000      37000      43000       18.6
  98. 20                   leno3                       6000      43000      43000      13.95
  99. 4.使用子分区查询。
  100. 按部门薪水连续的总和.
  101. (1)select deptno,sum(sal) over (partition by deptno order by ename) 按部门连续求总和 from emp;
  102. DEPTNO                       按部门连续求总和
  103. -------------------- ----------------
  104. 10                               2000
  105. 10                               5000
  106. 10                               7000
  107. 20                               4000
  108. 20                              12000
  109. 20                              18000
  110. 30                               5000
  111. 30                              11000
  112. 30                              18000
  113. (2)按部门求总和
  114. select deptno,sum(sal) over (partition by deptno) 按部门连续求总和 from emp ;
  115. DEPTNO                       按部门求总和
  116. -------------------- ----------------
  117. 10                               7000
  118. 10                               7000
  119. 10                               7000
  120. 20                              18000
  121. 20                              18000
  122. 20                              18000
  123. 30                              18000
  124. 30                              18000
  125. 30                              18000
  126. (3)不按部门连续求总和
  127. select deptno,sum(sal) over (order by deptno,ename) 不按部门连续求总和 from emp ;
  128. DEPTNO                        不按部门连续求总和
  129. -------------------- ------------------
  130. 10                                 2000
  131. 10                                 5000
  132. 10                                 7000
  133. 20                                11000
  134. 20                                19000
  135. 20                                25000
  136. 30                                30000
  137. 30                                36000
  138. 30                                43000
  139. (4)不按部门,求所有员工总和,效果等同于sum(sal)
  140. select deptno,sum(sal) over (order by deptno,ename) 不按部门连续求总和 from emp ;
  141. DEPTNO                        不按部门连续求总和
  142. -------------------- ------------------
  143. 10                                 2000
  144. 10                                 5000
  145. 10                                 7000
  146. 20                                11000
  147. 20                                19000
  148. 20                                25000
  149. 30                                30000
  150. 30                                36000
  151. 30                                43000
  152. (5)select deptno,ename,sal,
  153.         sum(sal) over (partition by deptno order by ename) 部门连续求和,--各部门的薪水"连续"求和
  154.         sum(sal) over (partition by deptno) 部门总和,   -- 部门统计的总和,同一部门总和不变
  155.         100*round(sal/sum(sal) over (partition by deptno),4) "部门份额(%)",
  156.         sum(sal) over (order by deptno,ename) 连续求和, --所有部门的薪水"连续"求和
  157.         sum(sal) over () 总和,   -- 此处sum(sal) over () 等同于sum(sal),所有员工的薪水总和
  158.         100*round(sal/sum(sal) over (),4) "总份额(%)"
  159.         from emp;
  160. DEPTNO               ENAME                        SAL       部门连续求和       部门总和     部门份额(%)       连续求和         总和     总份额(%)
  161. -------------------- -------------------- ----------- ------------ ---------- ----------- ---------- ---------- ----------
  162. 10                   andy1                       2000         2000       7000       28.57       2000      43000       4.65
  163. 10                   andy2                       3000         5000       7000       42.86       5000      43000       6.98
  164. 10                   andy3                       2000         7000       7000       28.57       7000      43000       4.65
  165. 20                   leno1                       4000         4000      18000       22.22      11000      43000        9.3
  166. 20                   leno2                       8000        12000      18000       44.44      19000      43000       18.6
  167. 20                   leno3                       6000        18000      18000       33.33      25000      43000      13.95
  168. 30                   jack1                       5000         5000      18000       27.78      30000      43000      11.63
  169. 30                   jack2                       6000        11000      18000       33.33      36000      43000      13.95
  170. 30                   jack3                       7000        18000      18000       38.89      43000      43000      16.28
  171. (6)TOP-N查询
  172. 6.1查询各部门中工资最高的记录
  173. select * from(select deptno,ename,sal,row_number() over(partition by deptno order by sal desc) topn from emp)  where topn=1;
  174. DEPTNO               ENAME                        SAL       TOPN
  175. -------------------- -------------------- ----------- ----------
  176. 10                   andy2                       3000          1
  177. 20                   leno2                       8000          1
  178. 30                   jack3                       7000          1
  179. 6.2按薪水高低对每个员工在本部门和整个公司内的排名进行排序。
  180. select deptno,ename,sal,dense_rank() over(partition by deptno order by sal desc nulls last) as dept_ranking,
  181.     dense_rank() over(order by sal desc nulls last) as company_ranking 
  182. from emp;
  183. DEPTNO               ENAME                        SAL DEPT_RANKING COMPANY_RANKING
  184. -------------------- -------------------- ----------- ------------ ---------------
  185. 20                   leno2                       8000            1               1
  186. 30                   jack3                       7000            1               2
  187. 20                   leno3                       6000            2               3
  188. 30                   jack2                       6000            2               3
  189. 30                   jack1                       5000            3               4
  190. 20                   leno1                       4000            3               5
  191. 10                   andy2                       3000            1               6
  192. 10                   andy1                       2000            2               7
  193. 10                   andy3                       2000            2               7
  194. 5 窗口windows
  195. 窗口子句是数据的滑动窗口,该窗口的分析函数将窗口看成一组。
  196. select deptno "部门ID",ename "部门名称",sal "工资",
  197.     sum(sal) over(partition by deptno order by ename rows 2 preceding) "sliding total"
  198. from emp order by deptno,ename;
  199. partition by deptno:相当于group by deptno
  200. rows 2:表示前两行相加
  201. preceding:表示从每个部门的第一行开始。
  202. 6 范围窗口
  203. Range windows仅对数据值和日期类型数据有效。(sal)
  204.  select deptno,ename,sal, count(*) over(order by sal asc range 3 preceding) 总计
  205. 7 行窗口
  206. 是物理单元,包含在窗口中的物理行数。对数据类型没有限制。
  207. 计算每个记录与其之前的2个记录的平均工资。
  208. set numformat 9999
  209. select ename,sal,
  210.     avg(sal) over(order by deptno asc rows 2 preceding) avgasc,
  211.     count(*) over(order by deptno asc rows 2 preceding) cntasc,
  212.     avg(sal) over(order by deptno desc rows 2 preceding) avgdes,
  213.     count(*) over(order by deptno desc rows 2 preceding) cntdes
  214. from emp order by deptno;  
  215. ENAME                        SAL     AVGASC     CNTASC     AVGDES     CNTDES
  216. -------------------- ----------- ---------- ---------- ---------- ----------
  217. andy1                       2000       2000          1 3666.66666          3
  218. andy2                       3000       2500          2 5666.66666          3
  219. andy3                       2000 2333.33333          3 2333.33333          3
  220. leno1                       4000       3000          3 5333.33333          3
  221. leno2                       8000 4666.66666          3 6333.33333          3
  222. leno3                       6000       6000          3       6000          3
  223. jack1                       5000 6333.33333          3       5500          2
  224. jack2                       6000 5666.66666          3       6000          1
  225. jack3                       7000       6000          3       6000          3
  226. 8 确定每组中的第一行或最后一行
  227. 使用first_vale和last_value函数可从一组中选择每一行和最后一行
  228. 统计工资每个部门最低或最高的员工信息。
  229. select deptno,ename,sal,first_value(ename) over(partition by deptno order by sal asc) as min_sal_has 
  230. from emp
  231. order by deptno,ename;
  232. select deptno,ename,sal,first_value(ename) over(partition by deptno order by sal desc) as min_sal_has 
  233. from emp
  234. order by deptno,ename;
  235. 9 统计各班成绩第一名的同学信息    NAME   CLASS S                         
  236.     ----- ----- ---------------------- 
  237.     fda    1      80                     
  238.     ffd    1      78                     
  239.     dss    1      95                     
  240.     cfe    2      74                     
  241.     gds    2      92                     
  242.     gf     3      99                     
  243.     ddd    3      99                     
  244.     adf    3      45                     
  245.     asdf   3      55                     
  246.     3dd    3      78              
  247.    
  248.     通过:   
  249.     --
  250.     select * from                                                                       
  251.     (                                                                            
  252.     select name,class,s,rank()over(partition by class order by s desc) mm from t2
  253.     )                                                                            
  254.     where mm=1 
  255.     --
  256.     得到结果:
  257.     NAME   CLASS S                       MM                                                                                        
  258.     ----- ----- ---------------------- ---------------------- 
  259.     dss    1      95                      1                      
  260.     gds    2      92                      1                      
  261.     gf     3      99                      1                      
  262.     ddd    3      99                      1          
  263.    
  264.     注意:
  265.     1.在求第一名成绩的时候,不能用row_number(),因为如果同班有两个并列第一,row_number()只返回一个结果          
  266.     2.rank()和dense_rank()的区别是:
  267.       --rank()是跳跃排序,有两个第二名时接下来就是第四名
  268.       --dense_rank()l是连续排序,有两个第二名时仍然跟着第三名
  269.          
  270.   
  271. 二:开窗函数           
  272.       开窗函数指定了分析函数工作的数据窗口大小,这个数据窗口大小可能会随着行的变化而变化,举例如下: 
  273. 1:     
  274.    over(order by salary) 按照salary排序进行累计,order by是个默认的开窗函数
  275.    over(partition by deptno)按照部门分区
  276. 2:
  277.   over(order by salary range between 5 preceding and 5 following)
  278.    每行对应的数据窗口是之前行幅度值不超过5,之后行幅度值不超过5
  279.    例如:对于以下列
  280.      aa
  281.      1
  282.      2
  283.      2
  284.      2
  285.      3
  286.      4
  287.      5
  288.      6
  289.      7
  290.      9
  291.    
  292.    sum(aa)over(order by aa range between 2 preceding and 2 following)
  293.    得出的结果是
  294.             AA                       SUM
  295.             ---------------------- ------------------------------------------------------- 
  296.             1                       10                                                      
  297.             2                       14                                                      
  298.             2                       14                                                      
  299.             2                       14                                                      
  300.             3                       18                                                      
  301.             4                       18                                                      
  302.             5                       22                                                      
  303.             6                       18                                                                
  304.             7                       22                                                                
  305.             9                       9                                                                 
  306.              
  307.    就是说,对于aa=5的一行 ,sum为   5-1<=aa<=5+2 的和
  308.    对于aa=2来说 ,sum=1+2+2+2+3+4=14     ;
  309.    又如 对于aa=9 ,9-1<=aa<=9+2 只有9一个数,所以sum=9    ;
  310.               
  311. 3:其它:
  312.      over(order by salary rows between 2 preceding and 4 following)
  313.           每行对应的数据窗口是之前2行,之后4行 
  314. 4:下面三条语句等效:           
  315.      over(order by salary rows between unbounded preceding and unbounded following)
  316.           每行对应的数据窗口是从第一行到最后一行,等效:
  317.      over(order by salary range between unbounded preceding and unbounded following)
  318.            等效
  319.      over(partition by null)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值