rownum = 3
не будет работать, потому что rownum
применяется к сгенерированному набору результатов.Первая строка в наборе результатов всегда имеет rownum = 1
.Ни один набор результатов не может соответствовать rownum = 3
, поэтому вы не получите строк назад.
Способ сделать это с помощью аналитической функции, такой как rank()
, dense_rank()
или row_number()
.
select * from
( select emp.*
, dense_rank() over (order by salary desc) rn
from hr.employees emp
)
where rn = 3
Использование rank()
, dense_rank()
или row_number()
зависит от того, как вы хотите обрабатывать связи.
Если вы используете row_number()
, вы получите третью строку в таблице, отсортированную по убыванию зарплаты.Будет ли это правильно, если у вас два сотрудника, получающие самую высокую зарплату?Или действительно четыре таких счастливых сотрудника)?
Если вы используете rank()
, подзапрос вернет пробелы в рейтинге, если есть связи, например, 1-й, 2-й =, 2-й =, 4-й, поэтому вы не получителюбой результат за третье место.
С другой стороны, dense_rank()
не имеет пробелов, если есть связи, например, 1-й, 2-й =, 2-й =, 3-й.Вот почему я использовал его выше.
Для записи эквивалентный запрос, использующий rownum
, потребует дополнительного вложенного подзапроса.
select * from (
select emp.*
, rownum as rn
from
( select * from hr.employees
order by salary desc) emp
)
where rn = 3
Это имеет тот же результат, что ианалитическое решение row_number()
, то есть оно игнорирует связи.