微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

学习Oracle分析函数(Analytic Functions)

Oracle提供了一些功能很强大的分析函数,使用这些函数可以完成可能需要存储过程来实现的需求。

分析函数计算基于一组数据行的聚合值,它们不同于聚合函数的是,它们为每一组返回多行结果。分析函数是除ORDER BY子句之外,在查询语句中最后执行的。所有的join和所有的WHERE,GROUP BY 和HAVING子句都在分析函数之前执行。所以分析函数只能出现在select或ORDER BY子句中。

下图为11.2版本官方文档中给出的语法示意图:

wKiom1j8YE-zfXLsAAGOKuDzgbs859.png

下面简单介绍一下各个部分:

analytic_function

指定分析函数的名字,后面列出了所有的分析函数

arguments

分析函数可以有0到3个参数。参数可以是任何数值类型或可以隐式转换为数值类型的其他非数值类型

analytic_clause

用OVER analytic_clause表明函数操作的是一个查询结果集。如果想过滤基于分析函数查询结果,需要使用嵌套子查询

query_partition_clause

用PARTITION BY子句来把查询结果集基于一个或多个value_expr分组。如果省略,分析函数把所有行当作一组。

order_by_clause

用order_by_claus指定在一组中数据如何排序。

ASC(default)|DESC

NULLS FirsT(default in DESC)|NULLS LAST(default in ASC)

windowing_clause

部分分析函数允许使用windowing_clause子句。

只有当指定了order_by_clause后才能指定这个子句。

ROWS指定使用物理行的window

RANGE指定使用逻辑偏移的window

详细信息请参考:http://docs.oracle.com/cd/E11882_01/server.112/e41084/functions004.htm#i81407

下面为所有的分析函数,带*号的函数允许使用windowing_clause:

AVG*
CORRCOUNTCOVAR_POPCOVAR_SAMPCUME_DIST
DENSE_RANK
FIRST
FIRST_VALUELAG
LAST
LAST_VALUELEAD
LISTAGG
MAXMEDIAN
MINNTH_VALUENTILE
PERCENT_RANK
PERCENTILE_CONT
PERCENTILE_DISC
RANK
RATIO_TO_REPORT
REGR_ (Linear Regression) FunctionsROW_NUMBER
STDDEVSTDDEV_POPSTDDEV_SAMPSUMVAR_POPVAR_SAMPVARIANCE*

以AVG为例介绍分析函数的使用:

AVG也是一个聚合函数

scott@TEST>selectavg(sal)fromemp;

AVG(SAL)
----------
2073.21429

作为分析函数的例子:

eg1:单独使用

scott@TEST>selectdeptno,ename,hiredate,sal,avg(sal)over()avgfromemp;

DEPTNOENAME			HIREDATE		SAL	AVG
-------------------------------------------------------------------------------
	20SMITH			1980-12-1700:00:00	8002073.21429
	30ALLEN			1981-02-2000:00:00	16002073.21429
	30WARD			1981-02-2200:00:00	12502073.21429
	20JOnes			1981-04-0200:00:00	29752073.21429
	30MARTIN			1981-09-2800:00:00	12502073.21429
	30BLAKE			1981-05-0100:00:00	28502073.21429
	10CLARK			1981-06-0900:00:00	24502073.21429
	20SCott			1987-04-1900:00:00	30002073.21429
	10KING			1981-11-1700:00:00	50002073.21429
	30TURNER			1981-09-0800:00:00	15002073.21429
	20AdamS			1987-05-2300:00:00	11002073.21429
	30JAMES			1981-12-0300:00:00	9502073.21429
	20FORD			1981-12-0300:00:00	30002073.21429
	10MILLER			1982-01-2300:00:00	13002073.21429

输出可以看出函数计算出了整体的平均值,并输出到每一行

eg2:使用query_partition_clause

scott@TEST>selectdeptno,avg(sal)over(partitionbydeptno)avgfromemp;

DEPTNOENAME			HIREDATE		SAL	AVG
-------------------------------------------------------------------------------
	10CLARK			1981-06-0900:00:00	24502916.66667
	10KING			1981-11-1700:00:00	50002916.66667
	10MILLER			1982-01-2300:00:00	13002916.66667
	20JOnes			1981-04-0200:00:00	29752175
	20FORD			1981-12-0300:00:00	30002175
	20AdamS			1987-05-2300:00:00	11002175
	20SMITH			1980-12-1700:00:00	8002175
	20SCott			1987-04-1900:00:00	30002175
	30WARD			1981-02-2200:00:00	12501566.66667
	30TURNER			1981-09-0800:00:00	15001566.66667
	30ALLEN			1981-02-2000:00:00	16001566.66667
	30JAMES			1981-12-0300:00:00	9501566.66667
	30BLAKE			1981-05-0100:00:00	28501566.66667
	30MARTIN			1981-09-2800:00:00	12501566.66667

scott@TEST>selectdeptno,avg(sal)fromempgroupbydeptno;

DEPTNOAVG(SAL)
--------------------
	301566.66667
	20	2175
	102916.66667

输出可以看出,AVG计算出了每个部门的平均值,并输出到对应的行。

eg3:使用order_by_clause

scott@TEST>selectdeptno,avg(sal)over(partitionbydeptnoorderbysal)avgfromemp;

DEPTNOENAME			HIREDATE		SAL	AVG
-------------------------------------------------------------------------------
	10MILLER			1982-01-2300:00:00	13001300
	10CLARK			1981-06-0900:00:00	24501875
	10KING			1981-11-1700:00:00	50002916.66667
	20SMITH			1980-12-1700:00:00	800	800
	20AdamS			1987-05-2300:00:00	1100	950
	20JOnes			1981-04-0200:00:00	29751625
	20SCott			1987-04-1900:00:00	30002175
	20FORD			1981-12-0300:00:00	30002175
	30JAMES			1981-12-0300:00:00	950	950
	30MARTIN			1981-09-2800:00:00	12501150
	30WARD			1981-02-2200:00:00	12501150
	30TURNER			1981-09-0800:00:00	15001237.5
	30ALLEN			1981-02-2000:00:00	16001310
	30BLAKE			1981-05-0100:00:00	28501566.66667

输出结果可以看出,每个部门的行都按sal做了升序排序。

eg4:使用windowing_clause

scott@TEST>selectdeptno,avg(sal)over(partitionbydeptnoorderbysalrowsBETWEEN1PRECEDINGAND1FOLLOWING)avgfromemp;

DEPTNOENAME			HIREDATE		SAL	AVG
-------------------------------------------------------------------------------
	10MILLER			1982-01-2300:00:00	13001875
	10CLARK			1981-06-0900:00:00	24502916.66667
	10KING			1981-11-1700:00:00	50003725
	20SMITH			1980-12-1700:00:00	800	950
	20AdamS			1987-05-2300:00:00	11001625
	20JOnes			1981-04-0200:00:00	29752358.33333
	20SCott			1987-04-1900:00:00	30002991.66667
	20FORD			1981-12-0300:00:00	30003000
	30JAMES			1981-12-0300:00:00	9501100
	30MARTIN			1981-09-2800:00:00	12501150
	30WARD			1981-02-2200:00:00	12501333.33333
	30TURNER			1981-09-0800:00:00	15001450
	30ALLEN			1981-02-2000:00:00	16001983.33333
	30BLAKE			1981-05-0100:00:00	28502225

输出的结果可以看出,分析函数对每一组中的每一行的输出结果是把它自己与它的上一行和下一行这三行求平均值。

分析函数太多,这里就不一一介绍功能了,有兴趣的同学可以点开上面的连接,去查看对应的功能

原文地址:https://www.jb51.cc/oracle/209516.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐