Oracle分析函数KEEP、DENSE_RANK的使用

今天学习sql优化语句过程中,看到有使用keep DENSE_RANK 减少表扫描,以前没有接触过这个,为此我去网上搜了下相关描述,如下所示

DENSE_RANK

功能描述:根据ORDER BY子句中表达式的值,从查询返回的每一行,计算它们与其它行的相对位置。组内的数据按ORDER BY子句排序,然后给每一行赋一个号,从而形成一个序列,该序列从1开始,往后累加。每次ORDER BY表达式的值发生变化时,该序列也随之增加。有同样值的行得到同样的数字序号(认为null时相等的)。密集的序列返回的时没有间隔的数。

FIRST

功能描述:从DENSE_RANK返回的集合中取出排在最前面的一个值的行(可能多行,因为值可能相等),因此完整的语法需要在开始处加上一个集合函数以从中取出记录。

LAST

功能描述:从DENSE_RANK返回的集合中取出排在最后面的一个值的行(可能多行,因为值可能相等),因此完整的语法需要在开始处加上一个集合函数以从中取出记录。
 
所以默认排序下,FIRST可以理解是取小值,LAST取大值。而前面的MIN或者MAX则是在KEEP的结果集中取某一字段的最大值或最小值。
 
 
下面我们开始动手操作,
create table t(ZGH VARCHAR2(10),WM VARCHAR2(10),RQ VARCHAR2(10))

select * from t for update;
--插入以下内容
/*A 1 20130101
A 2 20140102
A 1 20120102
B 3 20131001
B 2 20140102
B 3 20121004
*/

易错写法

select t.zgh,min(t.wm),min(t.rq) from t group by t.zgh;

 

最小值对应的wm为3,错误。

嵌套写法,效率一般

----普通写法 ,嵌套
select t1.zgh,t1.mwm,t2.mrq from (SELECT t.zgh,min(wm) mwm FROM T group by t.zgh) t1,(SELECT T.WM, min(RQ) AS MRQ FROM T GROUP BY T.WM) t2
where t1.mwm =t2.WM

KEEP DENSE_RANK 减少表扫描次数,效率得到保障

SELECT ZGH,
MIN(WM) KEEP(DENSE_RANK FIRST ORDER BY WM),
MIN(RQ) KEEP(DENSE_RANK FIRST ORDER BY WM)
FROM t
GROUP BY ZGH;

正确结果如下

 
 
 
原文地址:https://www.cnblogs.com/gudaozi/p/8572507.html