конкретный номер строки со всеми полями - PullRequest
0 голосов
/ 13 декабря 2018

У меня есть схема HR oracle, и в ней я хочу отобразить все поля сотрудников, у которых 3-я самая высокая зарплата.

Вот то, что я написал до сих пор, но оно ничего не возвращает.

select * from (
      select * from HR.EMPLOYEES 
       order by HR.EMPLOYEES.SALARY DESC) 
 where rownum=3

Я хочу получить этот результат без использования каких-либо функций, таких как dens_rank () и т. Д. Хотите сделать запрос простым.Но если кто-то может использовать аналитическую функцию и объяснить, как она работает, тогда я смогу понять, как ее использовать, но пока не понимаю использования таких функций, как dens_rank ().Есть идеи о том, что мне не хватает в моем запросе?

Ответы [ 2 ]

0 голосов
/ 13 декабря 2018

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(), то есть оно игнорирует связи.

0 голосов
/ 13 декабря 2018

В вашем случае вам нужно определить rownum в подзапросе без порядка по :

select * from
(
select rownum as rn, ee.* 
  from (
        select e.* from employees e order by salary desc
       ) ee
 )      
where rn=3;

PS Использование аналитических функций лучше, как сказал APC

...