我在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
无效
答案 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中给出:
答案 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执行查询的方式
- 首先是FROM / WHERE子句。
- ROWNUM被分配并递增到FROM / WHERE子句的每个输出行。
- 已应用SELECT。
- 应用GROUP BY。
- HAVING已应用。
- 已应用ORDER BY。
醇>
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
请注意,如果第二个为平局,则查询可能会返回多个值。这就是为什么外SELECT
是SELECT 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
因为在这种情况下,您要对子查询中的行进行编号。