Oracle带有Keep关键字的聚集函数的全面解析
**************************************************************************** 今天在一篇技术文章中看到ORACLE中有些函数带有KEEP关键字,上网查了些资料,对这个函数的说明要么语焉不详(各个关键字的语义没讲清除),要么理解有误(如把KEEP 理解为函数,或者根本没有理解什么是稠密排序),没办法,转过头来翻了翻ORACLE的SQL 参考手册,把对这个关键字相关理解与大家分享,若有错误,你请我吃油条。
首先说一下带有KEEP关键字的聚集函数的使用场景:
今天单位发工资了,你问和你同时参加工作的同办公室的老王“你发了多少?”,老王说“我发了20000元(奶奶的,工资真高,我才2000元)”,老王反问你“你哪?发了多少”,你回答“也是20000元”。老王听后不服气地说:“他奶奶的,你工资和我发的一样,老子却比你多工作了10年,哪里去讲理?!”。
这个场景应用到数据库中,你可以把老王和你的工资放到表里然后按照工资去排序,就能在查询结果中很清楚的看出相同工资的人员信息,但是只通过一个SQL语句你很难查出相同工资的人哪个年岁最大,哪个年岁最小?哪个参加工作早?哪个参加工作晚?。若只有上面描述场景的两个人或者几个人,似乎这不是问题,但如果有成百上千人有相同的工资哪?你如何去回答具有同样工资的人“哪个年岁最大,哪个年岁最小?哪个参加工作早?哪个参加工作晚”这样的问题哪?你当然可以通过其他方法来寻找到答案,但是我想可能下面介绍的方法却是最简单也是最高效的。
Oracle提供了这样的聚集函数,这些聚集函数同时也是分析函数,就可解决上面提出的类似问题,基本格式如下:
简化为:
Aggregate_function(arg) keep(dense_rank first|last order by exp)。
其中:
function为聚合函数,可以带有参数,如MAX(sal)等。
dense_rank first,dense_rank last:指按照什么方式进行排序以及排序后为聚集函数确定计算的记录(也成为行)范围,这两个关键字是说聚合函数的计算范围是按照稠密排序的第一名还是最后一名进行聚集计算。特别注意的是dense_rank指的就是稠密排序,也叫奥林匹克排序(可能是类似于奥运会运动员比赛的排名),也就是说可以有并列排名,而且排名是连续的,FIRST和LAST是指经过稠密排序后的第一名还是最后一名,这是聚合函数的计算范围,明白这点很重要;