如何在表中获得第二高的薪水员工

Vim*_*987 36 sql t-sql sql-server optimization

这是我今天下午得到的一个问题:

有一个表包含员工的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)
Run Code Online (Sandbox Code Playgroud)

我认为这很难看,但这是我脑海中唯一的解决方案.

你能建议我一个更好的查询吗?

非常感谢你.

ama*_*eur 34

SELECT * from Employee 
WHERE Salary IN (SELECT MAX(Salary) 
                 FROM Employee 
                 WHERE Salary NOT IN (SELECT MAX(Salary) 
                                      FFROM employee));

试试这样..

  • 这种方法不是很可扩展.想象一下,如果你想查询第10名受薪最高的员工!更好的方法是按工资排序然后限制输出中的记录. (3认同)
  • 非常简单:) (2认同)

Mar*_*ith 32

要获得可以使用的第二高工资额的员工姓名.

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

如果Salary被编入索引,则以下可能更有效,尤其是如果有很多员工.

SELECT Name
FROM   Employees
WHERE  Salary = (SELECT MIN(Salary)
                 FROM   (SELECT DISTINCT TOP (2) Salary
                         FROM   Employees
                         ORDER  BY Salary DESC) T);
Run Code Online (Sandbox Code Playgroud)

测试脚本

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)  
Run Code Online (Sandbox Code Playgroud)


mee*_*h55 11

这可能对你有帮助

SELECT 
      MIN(SALARY) 
FROM 
      EMP 
WHERE 
      SALARY in (SELECT 
                      DISTINCT TOP 2 SALARY 
                 FROM 
                      EMP 
                 ORDER BY 
                      SALARY DESC
                )
Run Code Online (Sandbox Code Playgroud)

我们可以通过放置(where )来找到任何最高薪水nthnn > 02

我们提出的 5 最高薪水的例子n = 5


mar*_*c_s 8

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
Run Code Online (Sandbox Code Playgroud)

DENSE_RANK() 将给你所有薪水第二高的员工 - 无论有多少员工拥有(相同的)最高薪水.


Pra*_*til 6

以下所有查询都适用于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;
Run Code Online (Sandbox Code Playgroud)


Kau*_*ele 5

另一种直观的方式是: - 假设我们想要找到第N个最高薪水

1)按照工资的降序对员工进行排序

2)使用rownum获取前N个记录.所以在这一步中,这里的第N个记录是第N个最高薪水

3)现在按升序对此临时结果进行排序.因此,第N个最高工资现在是第一个记录

4)从这个临时结果中获取第一条记录.

这将是第N个最高薪水.

select * from 
 (select * from 
   (select * from  
       (select * from emp order by sal desc)  
   where rownum<=:N )  
 order by sal )
where rownum=1;
Run Code Online (Sandbox Code Playgroud)

如果有重复的工资,那么在最里面的查询中可以使用distinct.

select * from 
 (select * from 
   (select * from  
       (select distinct(sal) from emp order by 1 desc)  
   where rownum<=:N )  
 order by sal )
where rownum=1;
Run Code Online (Sandbox Code Playgroud)


ste*_*ave 5

select MAX(Salary) from Employee WHERE Salary NOT IN (select MAX(Salary) from Employee );
Run Code Online (Sandbox Code Playgroud)


REM*_*ITH 5

最简单的方法就是使用OFFSET。不仅是第二,我们可以使用偏移量查询任何位置。

SELECT SALARY,NAME FROM EMPLOYEE ORDER BY SALARY DESC LIMIT 1 OFFSET 1-第二

SELECT SALARY,NAME FROM EMPLOYEE ORDER BY SALARY DESC LIMIT 1 OFFSET 9——第十