Выбор второй строки таблицы с помощью rownum - PullRequest
20 голосов
/ 11 февраля 2012

Я пробовал следующий запрос:

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?

Ответы [ 7 ]

50 голосов
/ 11 февраля 2012

Чтобы объяснить это поведение, нам нужно понять, как Oracle обрабатывает ROWNUM. При назначении ROWNUM для строки Oracle начинается с 1 и увеличивает значение только при выборе строки; то есть когда все условия в предложении WHERE выполнены. Поскольку наше состояние требует что ROWNUM больше 2, строки не выбраны и ROWNUM никогда не увеличивается больше 1.

Суть в том, что следующие условия будут работать как ожидается.

.. ГДЕ rownum = 1;

.. ГДЕ rownum <= 10; </p>

Хотя запросы с этими условиями всегда будут возвращать ноль строк.

.. ГДЕ 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;

EDIT : я исправил запрос, чтобы получить rownum после заказа по sal desc

8 голосов
/ 11 февраля 2012

В первом запросе первая строка будет иметь 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                   
1 голос
/ 09 мая 2017

Для n-го ряда с использованием rownum в oracle:

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;
1 голос
/ 11 февраля 2012

Попробуйте это:

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

ССЫЛКА

0 голосов
/ 08 декабря 2016
Select * From (SELECT *,
  ROW_NUMBER() OVER(ORDER BY column_name  DESC) AS mRow

FROM table_name 

WHERE condition) as TT
Where TT.mRow=2;
0 голосов
/ 10 мая 2016

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

0 голосов
/ 07 июля 2015

выберите empno из (
выберите empno, rownum как ром
из emp,
упорядочите по sal desc
)
, где ром = 2;

...