分析函数之分析语句学习--Over(Analytic_clause)

问题帖子:http://topic.csdn.net/u/20110212/11/d16c9fe3-ae21-48af-878d-37ec597b5f9e.html?46437

 

分析这样的问题,刚开始我还以为是数据的问题造成的,可是仔细想想,不应该的,于是从最明显的分析函数入手,官方文档如下

http://download.oracle.com/docs/cd/E11882_01/server.112/e17118/functions085.htm#SQLRF00655

 

看了次官方帖,发现所有的语句语法都写的多了红色的部分:

ORDER BY salary ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED
               FOLLOWING

同时官方里有段话出现的windowing_clause 不是很理解:

 

If you omit the windowing_clause of the analytic_clause, it defaults to RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW. This default sometimes returns an unexpected value, because the last value in the window is at the bottom of the window, which is not fixed. It keeps changing as the current  row changes. For expected results, specify the windowing_clause as RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING. Alternatively, you can specify the windowing_clause as RANGE BETWEEN CURRENT ROW ANDUNBOUNDED FOLLOWING.

可以看到analytic_clause在LAST_VALUE语法图里的OVER(analytic_clause)里,于是再次找到官方对analytic_clause的解释如下:

http://download.oracle.com/docs/cd/E11882_01/server.112/e17118/functions004.htm#SQLRF06174

 

中文贴:http://www.itpub.net/thread-1028584-1-1.html

 

 

由上2贴,再次学习下开窗函数的分析语句!

 

1:首先创建表和数据

CREATE  TABLE TEST AS SELECT * FROM
  (SELECT '001' emp_id, '101' manager_id, 1 lev, 0 part     FROM DUAL
      UNION
      SELECT '101' emp_id, '201' manager_id, 2 lev, 0 part   FROM DUAL
      UNION
      SELECT '201' emp_id, '301' manager_id, 3 lev, 0 part    FROM DUAL
      UNION
      SELECT '401' emp_id, '405' manager_id, 1 lev, 1 part    FROM DUAL
      UNION
      SELECT '108' emp_id, '401' manager_id, 2 lev, 1 part    FROM DUAL)

 

2:给出的开窗函数的分析语句解释(官方的语法图更清晰

Analytic_clause的语法如下:
[ query_partition_clause ] [ order_by_clause [ windowing_clause ] ]

这里:
query_partition_clause是查询分组子句;
order_by_clause是分组排序子句;
windowing_clause是窗口范围子句。

分析函数在查询结果集确定之后才开始进行计算,Analytic_clause就是用来定义函数怎样对查询结果集进行分组计算的。

根据Oracle对查询和分析函数的处理方法可知,在select和order by子句中都可以使用分析函数。

query_partition_by、order_by_clause和windowing_clause三个子句是可选的,将三个子句分别简记为p,o,w。
合法的组合方式有如下6种:
1).        Pow
(query_partition_clause order_by_clause windowing_clause)
分组,排序,定义窗口范围
2).        Po
(query_partition_clause order_by_clause)
分组,排序,窗口默认为range between unbounded preceding and current row
3).        P
(query_partition_clause)
分组,不排序,没有窗口
4).        Ow
(order_by_clause windowing_clause)
分组为整个查询结果集,排序,定义窗口范围
5).        O
(order_by_clause)
分组为整个查询结果集,排序,窗口默认为range between unbounded preceding and current row
6).        Null
()
分组为整个查询结果集,不排序,没有窗口

因为只有存在order_by_clause,才能有windowing_clause,故不存在如下两种形式的组合:
pw(query_partition_clause windowing_clause)
w(windowing_clause)
总结:
1).        对于是否存在order_by_clause,分析函数可以分为两类,含有order_by_clause的一般称为windowing function,不含的称为reporting function。
2).        Windowing function,对查询结果集进行分组,排序,根据窗口范围计算分组中每一行的函数结果。
3).        Reporting function,对查询结果集进行分组,不排序,窗口范围为整个分组,在每一个分组内,计算整个分组的函数值,再将函数值分别赋给分组内的每一行。

3:运行语句:

 

select first_value (emp_id) over (partition by part order by lev asc) first_e_id_asc, first_value (emp_id) over (partition by part order by lev desc) first_e_id_desc, first_value (emp_id) over (partition by part) first_e_id_p, last_value (emp_id) over (partition by part order by lev asc) last_e_id_asc, last_value (emp_id) over (partition by part order by lev desc) last_e_id_desc_error, last_value (emp_id) over (partition by part) last_e_id_p, last_value (emp_id) over (partition by part order by lev desc ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) last_e_id_desc_right, emp_id, manager_id m_id, lev, part from test;

结果:

001,201,201,201,201,001,001,201,301,3,0
001,201,201,101,101,001,001,101,201,2,0
001,201,201,001,001,001,001,001,101,1,0
401,108,108,108,108,401,401,108,401,2,1
401,108,108,401,401,401,401,401,405,1,1

 

运行语句和结果后,针对文档里讲的就很清晰明了了!谨以为记!

 

你可能感兴趣的:(分析函数之分析语句学习--Over(Analytic_clause))