Запрос SQL, чтобы найти N-ую самую высокую зарплату из таблицы зарплат - PullRequest
24 голосов
/ 03 октября 2010

Как найти N-ую самую высокую зарплату в таблице, содержащей зарплаты в SQL Server?

Ответы [ 11 ]

33 голосов
/ 03 октября 2010

Вы можете использовать общее табличное выражение (CTE), чтобы получить ответ.

Допустим, у вас есть следующие зарплаты в таблице Зарплаты:

 EmployeeID  Salary
--------------------
     10101   50,000
     90140   35,000
     90151   72,000
     18010   39,000
     92389   80,000

Мы будем использовать:

DECLARE @N int
SET @N = 3  -- Change the value here to pick a different salary rank

SELECT Salary
FROM (
    SELECT row_number() OVER (ORDER BY Salary DESC) as SalaryRank, Salary
    FROM Salaries
) as SalaryCTE
WHERE SalaryRank = @N

Это создаст номер строки для каждой строки послеон был отсортирован по зарплате в порядке убывания, а затем извлечен третий ряд (который содержит третью по величине запись).


Для тех из вас, кто не хочет CTE (или застрял в SQL 2000):

[ Примечание : это заметно хужечем приведенный выше пример;их параллельное выполнение с планами исключений показывает стоимость запроса 36% для CTE и 64% для подзапроса]:

SELECT TOP 1 Salary
FROM 
(
    SELECT TOP N Salary
    FROM Salaries
    ORDER BY Salary DESC
) SalarySubquery
ORDER BY Salary ASC

, где N определено вами.

SalarySubquery - это псевдоним, который я дал подзапросу, или запрос в скобках.

Что делает подзапрос, он выбирает верхние N зарплат (в данном случае мы скажем 3 ) и упорядочивает их по наибольшей зарплате.

Если мы хотим увидеть третий по величине оклад, подзапрос вернет:

 Salary
-----------
80,000
72,000
50,000

Внешний запрос затем выбирает первый оклад из подзапроса, за исключением того, что мы сортируем его по возрастаниюна этот раз, который сортируется от наименьшего к наибольшему, поэтому 50 000 будет первой отсортированной записью по возрастанию.

Как видите, 50 000 - это действительно третья самая высокая зарплата в примере.

12 голосов
/ 03 октября 2010

Вы можете использовать row_number, чтобы выбрать конкретную строку. Например, 42-я самая высокая зарплата:

select  *
from    (
        select  row_number() over (order by Salary desc) as rn
        ,       *
        from    YourTable
        ) as Subquery
where   rn = 42

Оконные функции типа row_number могут появляться только в предложениях select или order by. Обходной путь - размещение row_number в подзапросе.

6 голосов
/ 07 апреля 2011
select MIN(salary) from (
select top 5 salary from employees order by salary desc) x
5 голосов
/ 25 апреля 2013
EmpID   Name    Salary
1   A   100
2   B   800
3   C   300
4   D   400
5   E   500
6   F   200
7   G   600

SELECT * FROM Employee E1
WHERE (N-1) = (
                SELECT COUNT(DISTINCT(E2.Salary))
                FROM Employee E2
                WHERE E2.Salary > E1.Salary
              )

Предположим, вы хотите найти 5-ую самую высокую зарплату, что означает, что всего 4 сотрудника имеют зарплату, превышающую 5-ую самую высокую.Поэтому для каждой строки из внешнего запроса проверьте общее количество зарплат, превышающее текущую зарплату.Внешний запрос сначала будет работать для 100 и проверять количество зарплат больше 100. Это будет 6, не соответствует (5-1) = 6, где предложение externalquery.Затем для 800 и проверки количества зарплат, превышающих 800, 4=0 false, затем работают для 300, и, наконец, в таблице полностью 4 записи, которые больше 300. Поэтому 4=4 будет соответствовать предложению where и вернет3 C 300.

2 голосов
/ 10 января 2013

попробуй ...

use table_name
select MAX(salary)
from emp_salary
WHERE marks NOT IN (select MAX(marks)
from student_marks )
1 голос
/ 05 февраля 2014

Решение 1: Этот SQL для определения N-й наивысшей заработной платы должен работать в SQL Server, MySQL, DB2, Oracle, Teradata и почти во всех других СУБД: (примечание: низкая производительность из-за подзапроса)

SELECT * /*This is the outer query part */
FROM Employee Emp1
WHERE (N-1) = ( /* Subquery starts here */
SELECT COUNT(DISTINCT(Emp2.Salary))
FROM Employee Emp2
WHERE Emp2.Salary > Emp1.Salary)

Самая важная вещь, которую нужно понять в приведенном выше запросе, состоит в том, что подзапрос оценивается каждый раз, когда строка обрабатывается внешним запросом.Другими словами, внутренний запрос не может быть обработан независимо от внешнего запроса, поскольку внутренний запрос также использует значение Emp1.

Чтобы найти N-ую самую высокую зарплату, мы просто находим зарплату, которая имеет точноN-1 зарплата больше, чем она сама.


Решение 2: Найдите n-ую самую высокую зарплату, используя ключевое слово TOP в SQL Server

SELECT TOP 1 Salary
FROM (
      SELECT DISTINCT TOP N Salary
      FROM Employee
      ORDER BY Salary DESC
      ) AS Emp
ORDER BY Salary

Решение 3: Найти n-ю самую высокую зарплату в SQL Server без использования TOP

SELECT Salary FROM Employee 
ORDER BY Salary DESC OFFSET N-1 ROW(S) 
FETCH FIRST ROW ONLY

Обратите внимание, что я лично не тестировал SQL выше, и я считаю, что он будет работать только вSQL Server 2012 и выше.

1 голос
/ 02 апреля 2013

Не забудьте использовать ключевое слово distinct: -

SELECT TOP 1 Salary
FROM 
(
    SELECT Distinct TOP N Salary
    FROM Salaries
    ORDER BY Salary DESC
) SalarySubquery
ORDER BY Salary ASC
1 голос
/ 16 ноября 2012

Простой способ БЕЗ использования какой-либо специальной функции, специфичной для Oracle, MySQL и т. Д. Допустим, в таблице EMPLOYEE зарплаты можно повторять.Используйте запрос, чтобы узнать ранг каждого ID.

select  *
from  (
select tout.sal, id, (select count(*) +1 from (select distinct(sal) distsal from     
EMPLOYEE ) where  distsal >tout.sal)  as rank  from EMPLOYEE tout
) result
order by rank

Сначала мы узнаем различные зарплаты.Затем мы узнаем количество разных зарплат, превышающих каждый ряд.Это не что иное, как звание этого идентификатора.Для самой высокой зарплаты этот счет будет равен нулю.Итак, «+1» делается, чтобы начать ранг с 1.

Теперь мы можем получить идентификаторы с N-м рангом, добавив выражение where к вышеуказанному запросу.

0 голосов
/ 07 марта 2018
SELECT * FROM 
(select distinct postalcode  from Customers order by postalcode DESC)
limit 4,1;

4 здесь означает оставить первые 4 и показать следующие 1.

Попробуйте, это работает для меня.

0 голосов
/ 19 марта 2013

Самый простой способ - получить 2nd higest salary из table в SQL:

sql> select max(sal) from emp where sal not in (select max(sal) from emp);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...