2012-02-11 68 views
17

选择表的第二行我曾尝试下面的查询:使用ROWNUM

select empno from (
        select empno 
        from emp 
        order by sal desc 
       ) 
where rownum = 2 

这不返回任何记录。

当我试图此查询

select rownum,empno from (
         select empno from emp order by sal desc) 

它给了我这样的输出:

ROWNUM EMPNO  
1  7802   
2  7809  
3  7813  
4  7823 

谁能告诉我什么是我的第一个查询的问题?为什么添加ROWNUM过滤器时不会返回任何记录?

回答

44

为了解释这种现象,我们需要了解甲骨文如何处理 ROWNUM。将ROWNUM分配给一行时,Oracle从1开始,只有 只在选中某行时递增该值;也就是说,当满足WHERE子句中的所有 条件时。由于我们的条件要求 即ROWNUM大于2,没有行选择ROWNUM是 没有被增加超过1

的底线是,如下列条件将作为 预期。

.. WHERE rownum = 1;

.. WHERE rownum < = 10;

虽然具有这些条件的查询将始终返回零行。

.. WHERE rownum = 2;

.. WHERE rownum> 10;

Understanding Oracle rownum

引用您应修改您以这种方式查询才能工作:

select empno 
from 
    (
    select empno, rownum as rn 
    from (
      select empno 
      from emp 
      order by sal desc 
     ) 
    ) 
where rn=2; 

编辑:我已经纠正了该查询后得到的rownum sal desc的订单

+0

:感谢您的解释+1 ...查询不值得因为我想要根据sal desc的顺序获取记录的rownum,如果我们将rownum放入内部查询中,查询dint工作,它会给我们rownum emp表的记录,而不是已排序数据的记录....感谢您的解释 – 2012-02-11 12:44:39

+0

良好的答案(+1),但您提出的查询将无法正常工作并返回第二薪酬最高的员工。你需要另一级别的子查询来确保ROWNUM被指定_after_ ORDER BY。 – 2012-02-11 13:15:40

+0

@BrankoDimitrijevic你是对的。我会更正答案 – 2012-02-11 13:20:19

1

试试这个:

SELECT ROW_NUMBER() OVER (ORDER BY empno) AS RowNum, 
     empno 
FROM tableName 
WHERE RowNumber = 2; 

段从来源:

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

REFERENCE

+0

:谢谢你的解决方案,但我没有寻求的解决方案在这里,我我正在寻找为什么上述查询不起作用的原因.. – 2012-02-11 12:31:54

+0

相信你的where语句应该有'RowNum'而不是'RowNumber' – 2016-04-12 21:57:48

7

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

结果:

EMPNO     SAL      
---------------------- ---------------------- 
3      7813     
+0

+1查询的详细说明 – 2012-02-11 13:26:29

+0

Pitty在选择*时变得非常复杂,如果您不想将rownum作为输出的一部分。特别是在进行连接或查询视图时。 – user6856 2015-02-10 16:37:18

0

从(
选择选择EMPNO empno,rownum作为朗姆酒
from emp,
order by sal desc

其中朗姆酒= 2;

+0

你好Deepak,欢迎来到SO!虽然你的答案可能是正确的,但与已经接受的答案相比,增加的价值是多少? Imho的答案是多余的,不会添加任何有用的信息。因此它不可能得到任何肯定的承认。专注于未解答的问题或增加具有附加价值的答案以获得某种声誉。 – cfi 2015-07-07 20:04:11

-1

您可以使用RANKDENSE_RANK来实现您在此尝试实现的目标。

+0

你应该提供一个例子 – Austin 2016-05-10 12:22:08

0
Select * From (SELECT *, 
    ROW_NUMBER() OVER(ORDER BY column_name DESC) AS mRow 

FROM table_name 

WHERE condition) as TT 
Where TT.mRow=2; 
1

在Oracle使用ROWNUM第n行:

select * from TEST WHERE ROWNUM<=n 
MINUS 
select * from TEST WHERE ROWNUM<=(n-1); 

举例第二行:

select * from TEST WHERE ROWNUM<=2 
MINUS 
select * from TEST WHERE ROWNUM<=1; 
+0

Kamruzzaman:必须有条件获取第n个记录,例如第二高薪水,在你的查询中没有这样的逻辑 – 2017-05-09 14:01:07