【问题标题】:Selecting the second row of a table using rownum使用 rownum 选择表的第二行
【发布时间】:2012-03-03 15:43:07
【问题描述】:

我尝试了以下查询:

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 过滤器时没有返回任何记录?

【问题讨论】:

    标签: sql oracle oracle10g rownum


    【解决方案1】:

    要解释这种行为,我们需要了解 Oracle 是如何处理的 行号。将 ROWNUM 分配给一行时,Oracle 从 1 开始, 仅在选择行时增加值;也就是说,当所有 WHERE 子句中的条件得到满足。由于我们的条件需要 ROWNUM 大于 2,没有选择行并且 ROWNUM 是 从未增加超过 1。

    最重要的是,以下条件将作为 预计。

    .. WHERE rownum = 1;

    .. WHERE rownum

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

    .. 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 after 按 sal desc 排序

    【讨论】:

    • :感谢您的解释+1 ...查询不值得,因为我希望根据sal desc的顺序获取记录的rownum,如果我们输入rownum,查询将起作用在内部查询中,它将为我们提供 emp 表的记录的 rownum,而不是排序数据....感谢您的解释
    • 很好的答案 (+1),但您提出的查询将无法正常工作并返回第二高薪员工。您将需要另一个级别的子查询以确保在 ORDER BY 之后分配 ROWNUM。
    • 作为一个小改进,您可以将中间查询减少到 rownum
    • @user6856 Oracle 总是优化这种查询。我提出的查询将只扫描一次emp表,并且在扫描时,内存中将只有两行,即薪水最高的那些。
    • @FlorinGhita 这就是甲骨文获得大笔报酬的原因。他们擅长优化。有时实际上尝试优化查询会使 oracle 变慢,因为它会使查询过于复杂而无法自动优化。
    【解决方案2】:

    第一个查询中,第一行的 ROWNUM = 1 因此将被拒绝。第二行也将有 ROWNUM = 1(因为之前的行被拒绝)并且也会被拒绝,第三行也会有 ROWNUM = 1(因为之前的所有行都被拒绝)并且也会被拒绝等等......网络结果是所有行都被拒绝。

    第二个查询不应返回您得到的结果。它应该正确分配 ROWNUM ORDER BY 之后。

    因此,您需要使用的不是 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                   
    

    【讨论】:

    • Pitty 如果您不想将 rownum 作为输出的一部分,则选择 * 时会变得更加复杂。尤其是在进行连接或查询视图时。
    【解决方案3】:

    试试这个:

    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

    【讨论】:

    • :感谢您的解决方案,但我不是在这里寻找解决方案,我正在寻找上述查询不起作用的原因..
    • 相信你的where 子句应该有RowNum 而不是RowNumber
    【解决方案4】:

    在 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;
    

    【讨论】:

    • Kamruzzaman : 必须有条件来获取第 n 条记录,例如第二高薪水,您的查询中没有这样的逻辑
    【解决方案5】:

    从(
    中选择empno 选择 empno,rownum 作为朗姆酒
    来自雇员,
    按 sal desc 订购
    )
    其中朗姆酒=2;

    【讨论】:

    • 您好,Deepak,欢迎来到 SO!虽然您的答案可能是正确的,但与已经接受的答案相比,附加值是多少?恕我直言,您的回答是多余的,并且没有添加任何有用的信息。因此,它不太可能收到任何肯定的确认。专注于未回答的问题或添加具有附加价值的答案以获得一些声誉。
    【解决方案6】:
    Select * From (SELECT *,
      ROW_NUMBER() OVER(ORDER BY column_name  DESC) AS mRow
    
    FROM table_name 
    
    WHERE condition) as TT
    Where TT.mRow=2;
    

    【讨论】:

      【解决方案7】:

      从 Oracle 中的表中选择第二行

      SELECT *
      FROM (SELECT * FROM emp ORDER BY rownum DESC)
      WHERE rownum=1
      

      【讨论】:

        【解决方案8】:

        试试这个方法 100% 有效 SQL> SELECT * FROM STUD;

        RNUMBER 个名字标记


           104 mahesh                       85
           101 DHANU                        20
           102 BHARATH                      10
           100 RAJ                          50
           103 GOPI                         65
        

        SQL> select * from(select MARKS,ROWNUM AS RS from (select * from stud order by marking desc)) where RS=2;

         MARKS         RS
        

            65          2
        

        SQL>

        【讨论】:

          【解决方案9】:

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

          【讨论】:

          • 你应该提供一个例子
          【解决方案10】:

          试试这个查询 100% 工作

          Select * from(select rownum as rn,emp.* from emp) 其中 rn=2;

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-04-09
            • 2019-09-16
            • 1970-01-01
            • 2016-11-09
            • 2011-09-28
            • 2011-12-28
            • 1970-01-01
            • 2011-03-17
            相关资源
            最近更新 更多