Gau*_*oni 21 sql oracle oracle10g rownum
我试过以下查询:
select empno from (
select empno
from emp
order by sal desc
)
where rownum = 2
Run Code Online (Sandbox Code Playgroud)
这不会返回任何记录.
当我尝试这个查询
select rownum,empno from (
select empno from emp order by sal desc)
Run Code Online (Sandbox Code Playgroud)
它给了我这个输出:
ROWNUM EMPNO
1 7802
2 7809
3 7813
4 7823
Run Code Online (Sandbox Code Playgroud)
谁能告诉我第一次查询的问题是什么?为什么在添加ROWNUM过滤器时没有返回任何记录?
Flo*_*ita 53
要解释这种行为,我们需要了解Oracle如何处理ROWNUM.将ROWNUM分配给某行时,Oracle从1开始,仅在选择行时递增该值; 也就是说,当满足WHERE子句中的所有条件时.由于我们的条件要求ROWNUM大于2,因此不会选择任何行,并且ROWNUM永远不会超过1.
最重要的是,以下条件将按预期工作.
..在哪里rownum = 1;
..在哪里rownum <= 10;
虽然具有这些条件的查询将始终返回零行.
..在哪里rownum = 2;
..在哪里rownum> 10;
您应该以这种方式修改查询以便工作:
select empno
from
(
select empno, rownum as rn
from (
select empno
from emp
order by sal desc
)
)
where rn=2;
Run Code Online (Sandbox Code Playgroud)
编辑:我已经更正了查询,以获得sal desc订单后的rownum
在第一个查询中,第一行将具有ROWNUM = 1,因此将被拒绝.第二行也有ROWNUM = 1(因为之前的行被拒绝)也被拒绝,第三行也有ROWNUM = 1(因为它之前的所有行都被拒绝了)也被拒绝了......网结果是所有行都被拒绝.
在第二个查询不应该返回你得到的结果.它应该在 ORDER BY 之后正确分配ROWNUM .
由于所有这些,您需要使用不是2个而是3个级别的子查询,如下所示:
SELECT EMPNO, SAL FROM ( -- Make sure row is not rejected before next ROWNUM can be assigned.
SELECT EMPNO, SAL, ROWNUM R FROM ( -- Make sure ROWNUM is assigned after ORDER BY.
SELECT EMPNO, SAL
FROM EMP
ORDER BY SAL DESC
)
)
WHERE R = 2
Run Code Online (Sandbox Code Playgroud)
结果:
EMPNO SAL
---------------------- ----------------------
3 7813
Run Code Online (Sandbox Code Playgroud)