使用rownum选择表的第二行

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;

引自了解Oracle rownum

您应该以这种方式修改查询以便工作:

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


Bra*_*vic 8

在第一个查询中,第一行将具有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)