Выбор второй строки таблицы с помощью 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?

Ответ 1

Чтобы объяснить это поведение, нам нужно понять, как 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;

РЕДАКТИРОВАТЬ: я исправил запрос, чтобы получить rownum после заказа по Sal Desc

Ответ 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                   

Ответ 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

ССЫЛКА

Ответ 4

Для n-й строки с использованием rownum в оракуле:

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;

Ответ 5

выберите empno из (
                         выберите empno, rownum as rum
                         от emp,
                         заказать по sal desc
                )
где rum = 2;

Ответ 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

Вы можете использовать RANK или DENSE_RANK, чтобы достичь того, чего вы пытаетесь достичь здесь.