Oracle提供了一些功能很强大的分析函数,使用这些函数可以完成可能需要存储过程来实现的需求。
分析函数计算基于一组数据行的聚合值,它们不同于聚合函数的是,它们为每一组返回多行结果。分析函数是除ORDER BY子句之外,在查询语句中最后执行的。所有的join和所有的WHERE,GROUP BY 和HAVING子句都在分析函数之前执行。所以分析函数只能出现在select或ORDER BY子句中。
下图为11.2版本官方文档中给出的语法示意图:
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.f2er.com/oracle/209516.html