Oracle之分析函数

Oracle的分析函数在有些时候很方便,以面向集合的思维重新看待数据。

本次实验数据接 Oracle之Group By

分析函数组成:分区子句、排序子句、开窗子句(滑动窗口)

开窗子句

语法:

[ROWS | RANGE] BETWEEN <Start expr> AND <End expr>

Whereas
<Start expr> is [UNBOUNDED PRECEDING | CURRENT ROW | n PRECEDING | n FOLLOWING]
<End expr> is [UNBOUNDED FOLLOWING | CURRENT ROW | n PRECEDING | n FOLLOWING]

一、以‘年份’、‘月份’、‘类别’、‘销售额’、‘本年最大销售额’格式统计苹果的销售信息

select year, month, category, sales, 
 max(sales) 
 over(partition by year order by year, month 
 rows between unbounded preceding and unbounded following) maxSales 
from sales_log 
where category = 'Apple';

结果(省略一部分结果):

YEAR MO CATEGORY        SALES   MAXSALES
---- -- ---------- ---------- ----------
2011 1  Apple             709        869
2011 2  Apple             105        869
2011 3  Apple             505        869
2011 4  Apple             869        869
...
2011 11 Apple             775        869
2011 12 Apple             220        869
2012 1  Apple             226        942
2012 2  Apple             942        942
2012 3  Apple             353        942
...
2012 10 Apple             785        942
2012 11 Apple             836        942
2012 12 Apple             763        942

解析:

上述查询语句中分区子句:

partition by year

要求“本年最大销售额”首先按照年将数据分成几个区域。

排序子句:

order by year, month 
按照年份、月份对每个区域中的数据进行排序

开窗子句:

rows between unbounded preceding and unbounded following

窗口为unbounded preceding(前面无边界)unbounded following(后面无边界)

下面画个图解释一下上面三个定义

                    分区 + 排序                                                      开窗 取得每个窗口的最大值                         

Oracle之分析函数               Oracle之分析函数

步骤:

1.按照year进行分区,,共分为三个区域2011、2012、2013

2.按照year,month进行排序

3.无边界开窗(即以整个分区为窗口),求出每个窗口的最大值

这个例子在开窗这块还不明显,下面在举个例子

二、以‘年份’、‘月份’、‘类别’、‘销售额’、‘本月前后一周的最大销售额’格式统计2011年苹果的销售信息

也就是说现在是三月,那么最后一列的值为二月、三月、四月中最大的销售额

SQL> select year, month, category, sales,
  2   max(sales)
  3   over(order by to_number(month) rows between 1 preceding and 1 following) maxSales
  4  from sales_log
  5  where category = 'Apple'
  6   and year = '2011';


YEAR MO CATEGORY        SALES   MAXSALES
---- -- ---------- ---------- ----------
2011 1  Apple             709        709
2011 2  Apple             105        709
2011 3  Apple             505        869
2011 4  Apple             869        869
2011 5  Apple             230        869
2011 6  Apple             460        862
2011 7  Apple             862        862
2011 8  Apple             674        862
2011 9  Apple             257        674
2011 10 Apple             669        775
2011 11 Apple             775        775
2011 12 Apple             220        775


12 rows selected.


Elapsed: 00:00:00.00
SQL> spool off

这次就没必要分区了,所有数据只有一个年份2011。但是数据一定要排序,不然月份乱套了。那就没法保证上一条数据就是上月的,写一条数据就是下月的了。

这次的分区子句为

rows between 1 preceding and 1 following
也就是前后各一行,符合语法  n PRECEDING | n FOLLOWING

可以把窗口看成一个滑块,如图

--->	2011	1	Apple	709	709
	2011	2	Apple	105	
	2011	3	Apple	505	
	...				
					

	2011	1	Apple	709	
--->	2011	2	Apple	105	709
	2011	3	Apple	505	
	...					
	
				
	...
	2011	2	Apple	105	
--->	2011	3	Apple	505	869
	2011	4	Apple	869	
	...

第一次当前行为一月值为709,前一行没有为null,下一行值为105。最大值为709

第二次当前行为二月值为105,前一行一月值为709,下一行三月值为505。最大值为709

第三次当前行为三月值为505,前一行二月值为105,下一行四月值为869。最大值为869

总之开窗子句相当于就是滑动在分区上的一个小滑块,每次滑动一行。滑块的大小(范围)就是开窗子句定义的。而我们每次分析的数据就是滑块中的数据。



你可能感兴趣的:(Oracle之分析函数)