如何使用rownum

时间:2013-04-12 04:34:54

标签: sql oracle rownum

我在oracle中有一个员工表,上面有姓名,工资和其他详细信息。

我想获得第二高的薪水,但却无法取得。

这个工作正常

with e_salary as (select distinct salary from employee)
select salary from e_salary
order by salary desc

并提供输出:

450000

61000

60000

50000

40000

30000

20000

6000

但是当我使用相同的查询获取第二个最高行而没有获得任何输出时

select salary
  from ( with e_salary as (select distinct salary from employee)
         select salary from e_salary order by salary desc)
 where rownum = 2

但是当我用rownum=2替换rownum<2时,它会给出前两个记录的输出。请有人解释为什么rownum=2无效

7 个答案:

答案 0 :(得分:3)

这将有效:

  

从中选择薪水(选择薪水,rownum为rn from(选择薪水)   来自e_salary order by salary desc))其中rn = 2;

为什么它不起作用:

将ROWNUM分配给某行时,Oracle从1开始,仅在选择行时增加该值;也就是说,当满足WHERE子句中的所有条件时。由于我们的条件要求ROWNUM大于2,因此不会选择任何行,并且ROWNUM永远不会超过1。

希望你现在很清楚。

答案 1 :(得分:2)

select ename  ,sal  ,rank() over (order by sal desc) ranking from emp;

试试这个。

关注此链接,有关第n个最高行的所有内容都在oracle中给出:

http://www.oratable.com/nth-highest-salary-in-oracle/

答案 2 :(得分:2)

使用rownum是一件棘手的事情。最安全的选择是仅在您想要限制要显示的结果数量时使用它。例如rownum&lt; 2或rownum&lt; = 5。

为什么rownum = 2不起作用?

请在此处阅读 - http://www.oracle.com/technetwork/issue-archive/2006/06-sep/o56asktom-086197.html

总之,这是oracle执行查询的方式

  
      
  1. 首先是FROM / WHERE子句。
  2.   
  3. ROWNUM被分配并递增到FROM / WHERE子句的每个输出行。
  4.   
  5. 已应用SELECT。
  6.   
  7. 应用GROUP BY。
  8.   
  9. HAVING已应用。
  10.   
  11. 已应用ORDER BY。
  12.   

rownum&lt; = 2子句将转换为

ROWNUM = 1
for x in 
( select * from emp )
loop
    exit when NOT(ROWNUM <= 2)
    OUTPUT record to temp
    ROWNUM = ROWNUM+1
end loop
SORT TEMP

如果你用NOT(ROWNUM&lt; = 2)用rownnum = 2改变退出,你可以看到它在第一次运行时会失败

所以,如果我不能使用rownum,我可以使用什么。尝试使用row_number()http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions137.htm

它有点像

SELECT last_name FROM 
   (SELECT last_name, ROW_NUMBER() OVER (ORDER BY last_name) R FROM employees)
   WHERE R BETWEEN 51 and 100;

答案 3 :(得分:1)

条件中的

rownum会在第一次失败时停止评估。在返回的第一行,rownum为1,因此它未通过rownum = 2测试并停止尝试。有一篇关于它的优秀文章here

要获得第二高薪,请使用Oracle分析DENSE_RANK函数:

SELECT DISTINCT Salary FROM (
  SELECT Salary, DENSE_RANK() OVER (ORDER BY Salary DESC) AS SalaryRank
  FROM e_salary)
WHERE SalaryRank = 2

请注意,如果第二个为平局,则查询可能会返回多个值。这就是为什么外SELECTSELECT DISTINCT

答案 4 :(得分:0)

首先,您应该了解rownum是什么。我举个例子,

 you want to get data with a filter and rownum=2, 
 first Oracle executes the sql with filter and get the first record, 
 give it the rownum 1, 
 and then compare it the rownum filter rownum=2, which doesn't match, so discard record, 
 then get second record, give it rownum=1(if the first record is matched then the rownum will  be 2)  too, then do the compare............ 

所以你可以找到原因。

答案 5 :(得分:0)

不使用 rownum 命令,您可以使用此查询获得第二高薪:

select MAX(Salary) from Employee 
WHERE Salary NOT IN 
(select MAX(Salary) from Employee )

,或者

select MAX(Salary) from Employee 
WHERE Salary <> 
(select MAX(Salary) from Employee )

查询第n个最高:

SELECT * FROM Employee Emp1 
WHERE (N-1) = 
(SELECT COUNT(DISTINCT(Emp2.Salary))FROM Employee Emp2 
WHERE Emp2.Salary > Emp1.Salary)

答案 6 :(得分:0)

根据我的理解,rownum对结果集中的行进行编号。

所以,在你的例子中:

从table1中选择*,其中rownum = 2

结果集中会有多少行?因此,什么rownum将分配给这样一行?你现在能看到为什么没有实际返回结果吗?

通常,您应该避免依赖于rownum或任何暗示订单结果的功能。试着考虑使用整套结果。

话虽如此,我相信以下内容可行:

select * from(select rownum as rn,table1。* from table1)as t where t.rn = 2

因为在这种情况下,您要对子查询中的行进行编号。