0

我在 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不起作用

4

7 回答 7

3

这将起作用:

从中选择薪水(选择薪水,rownum作为rn从(从e_salary按薪水顺序选择薪水))其中rn = 2;

为什么它不起作用:

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

希望你现在很清楚。

于 2013-04-12T05:11:46.753 回答
2
select ename  ,sal  ,rank() over (order by sal desc) ranking from emp;

试试这个。

按照这个链接,关于第 n 行的所有内容都在 oracle 中给出:

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

于 2013-04-12T04:48:30.657 回答
2

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

为什么 rownum=2 不起作用?

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

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

  1. FROM/WHERE 子句首先出现。
  2. 从 FROM/WHERE 子句为每个输出行分配并递增 ROWNUM。
  3. SELECT 被应用。
  4. 应用 GROUP BY。
  5. 应用了 HAVING。
  6. 应用 ORDER BY。

rownum<=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 <= 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;
于 2013-04-12T05:29:07.983 回答
1

rownum在第一次失败时停止评估。返回的第一行rownum是 1,因此它没有通过rownum = 2测试并停止尝试。这里有一篇很棒的文章。

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

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

请注意,如果第二次出现平局,则查询可能会返回多个值。这就是为什么外部SELECT是一个SELECT DISTINCT.

于 2013-04-12T04:49:51.930 回答
0

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

因此,在您的示例中:

select * from table1 where rownum=2

结果集中会有多少行?因此,应该为这样的行分配什么 rownum?你现在能明白为什么实际上没有返回结果吗?

通常,您应该避免依赖 rownum 或任何暗示结果顺序的功能。尝试考虑使用整个结果集。

话虽如此,我相信以下方法会起作用:

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

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

于 2013-04-12T05:42:04.297 回答
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)
于 2013-04-12T05:37:52.573 回答
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............ 

所以你可以找到原因。

于 2013-04-12T04:49:50.847 回答