Попытка найти запрос Oracle, чтобы найти n-ую самую высокую зарплату и среди них один с самым высоким опытом - PullRequest
0 голосов
/ 22 февраля 2019

Мне нужно найти имя человека с 3-й самой высокой зарплатой

Таблица, о которой идет речь, выглядит следующим образом:

Name       Salary    Experience
-------------------------------
Den        11000       114
Gerald     11000       148
Ellen      11000       174
Eleni      10500       149
Clara      10500       162
Janette    10000       156 
Peter      10000       150
Hermann    10000       204
Harrison   10000       169

Мне нужно найти имя человека, имеющего максимальный опыт работы, ив 3-й категории наивысшей зарплаты.

Итак, очевидно, что 3-я самая высокая зарплата составляет 10000, и максимальный опыт среди тех, у кого 3-я самая высокая зарплата, - Герман с опытом 204.

У меня есть запрос, чтобы найти 3-юсамая высокая зарплата:

select name, salary, experience 
from sal s1 
where 3 - 1 = (select count(distinct salary) 
               from sal s2 
               where s2.salary > s1.salary);

Но этот запрос возвращает 4 строки, и мне нужно знать, как я могу еще больше отфильтровать его в этом же запросе, чтобы найти Германа с показателем 204.

Ответы [ 3 ]

0 голосов
/ 22 февраля 2019

Используйте аналитическую функцию DENSE_RANK, чтобы найти 3-ую самую высокую зарплату, и аналитическую функцию ROW_NUMBER (или RANK или DENSE_RANK) с предложением PARTITION BY, чтобы найти самый высокий опыт на зарплату.Для этого требуется только одно сканирование таблицы / индекса.

Установка Oracle :

CREATE TABLE table_name ( Name, Salary, Experience ) AS
SELECT 'Den',      11000, 114 FROM DUAL UNION ALL
SELECT 'Gerald',   11000, 148 FROM DUAL UNION ALL
SELECT 'Ellen',    11000, 174 FROM DUAL UNION ALL
SELECT 'Eleni',    10500, 149 FROM DUAL UNION ALL
SELECT 'Clara',    10500, 162 FROM DUAL UNION ALL
SELECT 'Janette',  10000, 156 FROM DUAL UNION ALL
SELECT 'Peter',    10000, 150 FROM DUAL UNION ALL
SELECT 'Hermann',  10000, 204 FROM DUAL UNION ALL
SELECT 'Harrison', 10000, 169 FROM DUAL

Запрос : если вы хотите найти "человекаимея максимальный опыт работы в 3-й категории наивысшей зарплаты ":

SELECT Name, Salary, Experience
FROM   (
  SELECT t.*,
         DENSE_RANK() OVER ( ORDER BY Salary DESC ) AS s_rank,
         ROW_NUMBER() OVER ( PARTITION BY Salary ORDER BY Experience DESC )
           AS Exp_rownum
  FROM   table_name t
)
WHERE s_rank = 3
AND   Exp_rownum = 1;

Если вы поменяете аналитическую функцию ROW_NUMBER() на RANK() или DENSE_RANK(), тогда будет возвращено несколько человек, если они связаны сСовместный наивысший опыт работы в 3-й категории наивысшей зарплаты.

Вывод :

NAME    | SALARY | EXPERIENCE
:------ | -----: | ---------:
Hermann |  10000 |        204

Запрос : если вы хотите найти "человека, имеющегоМаксимальный опыт и (также) в 3-й категории наивысшей зарплаты ":

Просто возьмите запрос выше и удалите предложение PARTITION BY.

SELECT Name, Salary, Experience
FROM   (
  SELECT t.*,
         DENSE_RANK() OVER ( ORDER BY Salary DESC ) AS s_rank,
         ROW_NUMBER() OVER ( ORDER BY Experience DESC ) AS Exp_rownum
  FROM   table_name t
)
WHERE s_rank = 3
AND   Exp_rownum = 1;

Вывод :

(Примечание: если опыт Германа был 173, то это не вернуло бы ни одной строки, так как у Эллен был бы самый высокий опыт, но она не была бы в третьей самой высокой шкале зарплаты, а Герман был бы в третьей самой высокойзарплата, но будет иметь только 2-й самый высокий опыт.)

NAME    | SALARY | EXPERIENCE
:------ | -----: | ---------:
Hermann |  10000 |        204

дБ <> скрипка здесь

0 голосов
/ 22 февраля 2019

Этот запрос использует ROWNUM и MAX, чтобы найти правильную строку.В самом внутреннем подзапросе максимальный опыт извлекается для каждого уровня зарплаты, упорядоченный по убыванию зарплаты, а затем во внешнем подзапросе добавляются номера строк, и это соединяется с исходной таблицей, чтобы найти правильные строки (и)

SELECT s.name, s.salary, s.experience
FROM sal s
JOIN (SELECT s2.*, ROWNUM rnum
      FROM (SELECT salary, max(experience) AS m_exp
            FROM sal 
            GROUP BY salary
            ORDER BY salary DESC) s2) s3 ON s3.salary = s.salary AND 
                                            s3.m_exp = s.experience AND 
                                            rnum = 3 
0 голосов
/ 22 февраля 2019

Вы не запрашиваете опыт.Поэтому вы должны добавить предложение where:

select name, salary, experience 
from sal s1 
where 3 - 1 = (select count(distinct salary) 
               from sal s2 
               where s2.salary > s1.salary)
  and experience = (select max(experience) from sal)

ОБНОВЛЕНИЕ

Альтернатива (максимальный опыт работы в пределах 3-й наивысшей зарплаты) должна быть:

select name, salary, experience 
from sal s1 
where 3 - 1 = (select count(distinct salary) 
               from sal s2 
               where s2.salary > s1.salary)
  and experience = (select max(experience)  from sal s3 
                    where 3 - 1 = (select count(distinct salary) 
                                   from sal s4 
                                   where s4.salary > s3.salary)
                    )
...