Как получить наивысшую зарплату сотрудников за столом - PullRequest
34 голосов
/ 14 сентября 2011

Это вопрос, который я получил сегодня днем:

Там в таблице содержатся ID, Имя и Зарплата сотрудников, получают имена сотрудников с наивысшей зарплатой в SQL Server

Вотмой ответ, я просто написал это на бумаге и не уверен, что это совершенно правильно, но, похоже, работает:

SELECT Name FROM Employees WHERE Salary = 
( SELECT DISTINCT TOP (1) Salary FROM Employees WHERE Salary NOT IN
 (SELECT DISTINCT TOP (1) Salary FROM Employees ORDER BY Salary DESCENDING)
ORDER BY Salary DESCENDING)

Я думаю, что это некрасиво, но это единственное решение, которое приходит мне в голову.

Можете ли вы предложить мне лучший запрос?

Большое спасибо.

Ответы [ 53 ]

34 голосов
/ 09 августа 2012
SELECT * from Employee 
WHERE Salary IN (SELECT MAX(Salary) 
                 FROM Employee 
                 WHERE Salary NOT IN (SELECT MAX(Salary) 
                                      FFROM employee));

Попробуй вот так ..

31 голосов
/ 14 сентября 2011

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

;WITH T AS
(
SELECT *,
       DENSE_RANK() OVER (ORDER BY Salary Desc) AS Rnk
FROM Employees
)
SELECT Name
FROM T
WHERE Rnk=2;

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

SELECT Name
FROM   Employees
WHERE  Salary = (SELECT MIN(Salary)
                 FROM   (SELECT DISTINCT TOP (2) Salary
                         FROM   Employees
                         ORDER  BY Salary DESC) T);

Тестовый скрипт

CREATE TABLE Employees
  (
     Name   VARCHAR(50),
     Salary FLOAT
  )

INSERT INTO Employees
SELECT TOP 1000000 s1.name,
                   abs(checksum(newid()))
FROM   sysobjects s1,
       sysobjects s2

CREATE NONCLUSTERED INDEX ix
  ON Employees(Salary)

SELECT Name
FROM   Employees
WHERE  Salary = (SELECT MIN(Salary)
                 FROM   (SELECT DISTINCT TOP (2) Salary
                         FROM   Employees
                         ORDER  BY Salary DESC) T);

WITH T
     AS (SELECT *,
                DENSE_RANK() OVER (ORDER BY Salary DESC) AS Rnk
         FROM   Employees)
SELECT Name
FROM   T
WHERE  Rnk = 2;

SELECT Name
FROM   Employees
WHERE  Salary = (SELECT DISTINCT TOP (1) Salary
                 FROM   Employees
                 WHERE  Salary NOT IN (SELECT DISTINCT TOP (1) Salary
                                       FROM   Employees
                                       ORDER  BY Salary DESC)
                 ORDER  BY Salary DESC)

SELECT Name
FROM   Employees
WHERE  Salary = (SELECT TOP 1 Salary
                 FROM   (SELECT TOP 2 Salary
                         FROM   Employees
                         ORDER  BY Salary DESC) sel
                 ORDER  BY Salary ASC)  
9 голосов
/ 13 февраля 2013

Это может помочь вам

SELECT 
      MIN(SALARY) 
FROM 
      EMP 
WHERE 
      SALARY in (SELECT 
                      DISTINCT TOP 2 SALARY 
                 FROM 
                      EMP 
                 ORDER BY 
                      SALARY DESC
                )

Мы можем найти любую n<sup>th</sup> самую высокую зарплату, поставив n (где n > 0) вместо 2

Пример для5 th самая высокая зарплата, которую мы ставим n = 5

7 голосов
/ 14 сентября 2011

Как насчет CTE?

;WITH Salaries AS
(
    SELECT Name, Salary,
       DENSE_RANK() OVER(ORDER BY Salary DESC) AS 'SalaryRank'
    FROM 
        dbo.Employees
)
SELECT Name, Salary
FROM Salaries  
WHERE SalaryRank = 2

DENSE_RANK() даст вам всех сотрудников, у которых вторая самая высокая зарплата - независимо от того, сколько сотрудников имеют (одинаковую) самую высокую зарплату.

5 голосов
/ 01 февраля 2013

Другой интуитивно понятный способ: - Предположим, мы хотим найти N-ую самую высокую зарплату, затем

1) Сортировать сотрудника в порядке убывания зарплаты

2) Взять первые N записей, используя rownum.Таким образом, на этом шаге N-я запись - это N-я самая высокая зарплата

3) Теперь рассортируйте этот временный результат в порядке возрастания.Таким образом, Nth самая высокая зарплата теперь является первой записью

4) Получить первую запись из этого временного результата.

Это будет N-ая самая высокая зарплата.

select * from 
 (select * from 
   (select * from  
       (select * from emp order by sal desc)  
   where rownum<=:N )  
 order by sal )
where rownum=1;

Если есть повторяющиеся зарплаты, то в самом внутреннем запросе можно использовать различные.

select * from 
 (select * from 
   (select * from  
       (select distinct(sal) from emp order by 1 desc)  
   where rownum<=:N )  
 order by sal )
where rownum=1;
4 голосов
/ 17 июля 2018

Все следующие запросы работают для MySQL :

SELECT MAX(salary) FROM Employee WHERE Salary NOT IN (SELECT Max(Salary) FROM Employee);

SELECT MAX(Salary) From Employee WHERE Salary < (SELECT Max(Salary) FROM Employee);

SELECT Salary FROM Employee ORDER BY Salary DESC LIMIT 1 OFFSET 1;

SELECT Salary FROM (SELECT Salary FROM Employee ORDER BY Salary DESC LIMIT 2) AS Emp ORDER BY Salary LIMIT 1;
3 голосов
/ 16 ноября 2012

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

Предположим, что таблица EMPLOYEE содержит данные, как показано ниже.Зарплаты можно повторить.enter image description here

Путем ручного анализа мы можем определить ранги следующим образом: -
enter image description here

Тот же результат может быть достигнут с помощью запроса

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

enter image description here

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

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

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
where rank = N;
3 голосов
/ 14 ноября 2013
select MAX(Salary) from Employee WHERE Salary NOT IN (select MAX(Salary) from Employee );
2 голосов
/ 14 сентября 2011

Приведенный ниже запрос может использоваться для поиска n-го максимального значения, просто замените 2 из n-го числа

select * from emp e1 where 2 =(select count(distinct(salary)) from emp e2
   where e2.emp >= e1.emp)
2 голосов
/ 14 сентября 2011

Я думаю, что вы хотели бы использовать DENSE_RANK, поскольку вы не знаете, сколько сотрудников имеют одинаковую зарплату, и вы сказали, что хотите иметь имена сотрудников.

CREATE TABLE #Test
(
    Id INT,
    Name NVARCHAR(12),
    Salary MONEY
)

SELECT x.Name, x.Salary
FROM
        (
        SELECT  Name, Salary, DENSE_RANK() OVER (ORDER BY Salary DESC) as Rnk
        FROM    #Test
        ) x
WHERE x.Rnk = 2

ROW_NUMBER даст вам уникальную нумерацию, даже если зарплата будет привязана, а простой RANK не даст вам «2» в качестве звания, если у вас есть несколько человек, которые связываются за самую высокую зарплату. Я исправил это, поскольку DENSE_RANK делает лучшую работу для этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...