梦见好多的军人:Oracle查找第n个最大值

来源:百度文库 编辑:中财网 时间:2024/05/08 01:45:50

Oracle查找第n个最大值

在国内外许多Oracle DBA站点上,有很多查找表中第n个最大值的小技巧,这些语句确实相当巧妙,它们都独辟蹊径地用到了Oracle表中的一个伪字段“level”。但是在很多情况下,这个语句变成了 美丽的陷阱。如果你想知道为什么,并怎样绕过它,请听我道来!
研究了几天,我发现一种衍生算法,即找出第n个和第m个最大值的差(如下):
列表一:
select max(salary) from empdetails
   where level = &n
   connect by prior salary>salary
   start with salary = ( select max(salary) from empdetails);
此后又发现如下算法,利用Oracle的伪字段level,从最大值开始,按值递减顺序,把记录逐步分层,最后找出第n个最大值和第m个最大值之间的差值。
列表二:
select a.nmax_salary – b.mmax_salary from
  (select max(salary) from empdetails
     where level = &n
     connect by prior salary > salary
     start with salary = (select (max(salary)) from empdetails)
   ) a ,
  (select max(salary) mmax_salary from empdetails
     where level = &m
     connect by prior salary > salary
     start with salary = (select (max(salary)) from empdetails)
   ) b ;
我为此算法的新奇赞叹了很久,值到一天我想利用这个方法时,才发现这个方法并不如想象中那么美妙。
我要从60多个不同值中找出第n个最大值时,输入此语句后,发现如同石沉大海、杳无音讯,屏幕上只有“Statement is running”的提示。为了了解Oracle是怎样分层的,我输入如下语句:
列表三:
select lpad(‘ ‘,level)||salary from empdetails
     connect by prior salary > salary
     start with salary = (select (max(salary)) from empdetails) ;
发现屏幕在不断输出结果,足足等了十多分钟,还在不停地滚动,我意识到这算法存在某些问题。
试着分析一下列表三的结果,发现这个语句的回送记录数与库中不同数值的个数是指数增长,其公式为 RecordsRe = 2Rdeferent_value – 1 ,要在60多个不同值中用该算法找出第n个最大值,不知要花多长时间,即使机器不停计算几百年也不会得到结果。
还有其它方法吗?当然有,比如定义个游标,自己作一个计数器,用一段script来完成。假设empdetails表以salary建了一个索引salary_I1,可以用下列语句来完成:
列表四:
select salary from
  (select /* + Index(empdetails,salary_I1) */ Rownum, Row_num, salary
      from empdetails)where Row_num = &1;
在列表四中,用到了Oracle表中的另一个伪字段rownum,还用到了Oracle的优化提示(hint)。要注意Index提示是必须的,如果没有它,rownum是个伪字段,它不能与整数作相等的运算。Oracle一般按照记录插入的顺序来返回rownum,并不排序,如果用到此hint就可按salary字段排序返回。
列表四找到了按salary字段排序后的第n个记录的salary值。若表中有多个记录有相同的salary 值,而我们只要找到第 n 个最大 salary 值,而不是第 n 个记录,可以用列表5 的语句来实现。
列表五:
select salary from
  (select rownum aa, salary from
     (select distinct salary from empdetails)
   )
   where aa = ( select count (distinct salary ) + 1 - &n from empdetails);
至此,不会再出现列表一和列表二语句运行时的情况了,找第n个最大值的目的终于达到了。

在一个n 个结点的二叉排序树中查找一个关键字,进行关键字比较次数最大值为? select选择第N个? N的最大值 一个凸n边形中恰有4个钝角,则n的最大值? 数学问题:一个凸n边形的内角,恰有4个钝角,则n的最大值为多少? 三角函数问题:为什么当区间有n个最大值和最小值时,若n=2k(k属于正整数)则区间有k个周期 三角函数问题:为什么当区间有n个最大值和最小值时,若n=2k(k属于正整数)则区间有k个周期 设n个新生中,任意3个人中有2个人相互认识,任意4个人中有2个不认识,试求n得最大值 编写程序求第N个月的兔子数量。 0.8*n-1.1^n+15的最大值是什么 第1个图形有1个圆,第2个有6个圆,第3个有19个,问第n个图形有几个圆。试用带n的式子表达。 1个小学最大值问题 vb中如何求n个数的最大值和最小值? 从一个具有n个结点的单链表中查找值等于X的结点时,在查找成功的情况下,需平均比较的次数为? 如何在n维空间m个数据中快速查找某个数据的一定距离内所有数据? ORACLE里如何获取前n行的值啊! 1/2,-4/5,9/10,-16/17,.....第N个是多少? 找规律 写出第n个正方形边长An的表达式 Excel中如何提取某个单元格从第N个字符开始的内容? 要使n^3(n的三次方) +100能被n+10整除的正整数n的最大值应该是 采用二分查找的方法查找长度为N的..... 死神第N季EDlife...~~~ 数学:找第n项 一个N边形的内角和小于2003度,那么N的最大值是?