数据库中的函数封装了一些常用的函数,比如日期类型和字符串类型之间的转换。每个数据库系统都有一些内置的功能,当然用户也可以自定义功能。在Oracle数据库中,函数可以分为三类:单行函数、分组函数(也称聚合函数)和分析函数。一行函数一行函数分为字符函数、数值函数、日期函数、转换函数和一般函数五种类型。例如:--case控制函数selectlower('HelloWorld')tolowercase,upper('HelloWorld')touppercasefromdual;--initcap:firstletteruppercaseselectinitcap('helloworld')firstcharacteruppercasefromdual;--字符控制函数--concat:字符连接函数,相当于||selectconcat('Hello','World')fromdual;分组函数分组函数“又称聚合函数”,可以用在select或select的having子句中,在select子串中使用时,常与GROUPBY一起使用。多行函数分为接受多个输入和返回一个输出。例如:--groupdata:求各部门的平均工资selectdeptno,avg(sal)frommempgroupbydeptno;--groupby作用于多列:按部门、不同工种、??统计平均工资--groupby作用于多列:firstGroupby第一列;如果相同,则按第二列分组selectdeptno,job,avg(sal)fromempgroupbydeptno,job;--:找到平均工资大于2000的部门selectdeptno,avg(sal)fromempgroupbydeptnohavingavg(sal)>2000;分析函数分析函数是Oracle专门用来解决复杂报表统计需求的强大函数。它可以对数据进行分组,然后根据分组计算出一些统计值,每组的每一行都可以返回一个统计值,为我们分析数据提供了一种简单高效的方法。在分析功能出现之前,我们不得不使用自连接查询、子查询或内联视图,甚至是复杂存储过程实现的语句。现在,只需要一条简单的SQL语句就可以执行,执行效率有了相当大的提升。提升。分析函数和分组函数的区别普通的分组函数是按groupby进行分组,每组返回一个统计值,而分析函数使用partitionbygrouping,每组的每一行都可以返回一个统计值。分析函数的形式下面列出常用的分析函数:row_number()over(partitionby...orderby...)rank()over(partitionby...orderby...)dense_rank()over(partitionby...orderby...)...)count()over(partitionby...orderby...)max()over(partitionby...orderby...)min()over(partitionby...orderby...)sum()over(partitionby...orderby...)avg()over(partitionby...orderby...)first_value()over(partitionby...orderby...)last_value()over(partitionby...orderby...)lag()over(partitionby...orderby...)lead()over(partitionby...orderby...)分析函数的常见应用场景一般可以解决此类问题:①查找上一年每个销售区域的Top10员工②按区域查找上年度总订单占区域总订单20%以上的客户③查找上年度销售最差的部门所在区域④找出上一年最好和最差的产品当我们看上面的曲estions,我们可以感觉到这些查询和我们日常遇到的查询有些不同,具体是:①需要对同一份数据进行不同层次的聚合操作②需要聚合表中的多条数据与相同的多次比较数据③需要对排序后的结果集进行额外的过滤操作,Oracle的资料还是比较容易找到“相比于DB2”,搜索关键词“Oracle分析函数”得到更多的相关用法,这些样例运行成功在scott用户下。例1,显示各部门员工的工资,显示该部门的***工资。对当前所有记录的上一条和下一条记录执行SQLselecte.deptno,e.empno,e.ename,e.sal,last_value(e.sal)over(partitionbye.deptnoorderbye.salrows--unboundedprecedingandunbounedfollowing,即所有记录在表中--unbounded:不受控制,绝对--preceding:before...--following:in...afterbetweenunboundedprecedingandunboundedfollowing)max_salfromempe;运行结果示例2,按deptno分组,然后计算每组值的和执行SQLselectempno,ename,deptno,sal,sum(sal)over(partitionbydeptnoorderbyename)max_salfromempe;运行结果示例3,当前行的summaryofthepreviousrow(rownum-1)tothenextrow(rownum+2)ofthecurrentrowexecutesSQLselectempno,ename,deptno,sal,--注意rowsbetween1precedingand1following指的是当前行的上一行(rownum-1)currentrowtothecurrentrowSummarysum(sal)over(partitionbydeptnoorderbyenamerowsbetween1precedingand2following)max_salfromempofthenextrow(rownum+2)该部门的平均工资,sum(sal)over(partitionbydeptno)该部门的总工资,count(sal)over(partitionbydeptno)部门员工数,dense_rank()over(partitionbydeptnoorderbysaldesc)部门工资排名1,row_number()over(partitionbydeptnoorderbysaldesc)该员工所在部门薪资排名2,dense_rank()over(orderbysaldesc)该人全公司薪资排名,min(sal)over(partitionbydeptno)该部门***薪资1,min(sal)keep(dense_rankfirstorderbysal)over(partitionbydeptno)***本部门2的薪水,first_value(sal)over(partitionbydeptnoorderbysal)***本部门3的薪水,max(sal)over(partitionbydeptno)***本部门1的薪水,max(sal)keep(dense_ranklastorderbysal)over(partitionbydeptno)***这个部门的薪水2,last_value(sal)over(partitionbydeptnoorderbysal)***这个部门的薪水3,last_value(sal)over(partitionbydeptnoorderbysalrowsbetweenunboundedprecedingandunboundedfollowing)***这个部门的薪水4,lag(ename,1,'00')over(orderbysaldesc)工资在前的人,lead(ename,1,'00')over(orderbysaldesc)工资在下一位的人fromempeorderbydeptno,sal,ename运算结果注意:"部门***工资1\2\3"等结果are相同,但他们使用不同的书写方法。last_value()的写法不同导致“本部门***工资3”和“本部门***工资4”的结果不一样,可以这样理解:默认的统计范围last_value()是unboundedpreceding和currentrow之间的rows,所以需要在unboundedpreceding和unboundedfollowing之间添加行才能得到正确的统计结果,“本部门4的***工资”的统计结果是正确的。【本文为专栏作者“朱国立”原创稿件,转载请通过作者微信公众号“开发者圆桌”联系授权】点此查看本作者更多好文
