SQL查询从工资表中查找第N个最高薪水

时间:2010-10-03 13:58:48

标签: sql sql-server tsql

如何在包含SQL Server工资的表中找到第N个最高工资?

11 个答案:

答案 0 :(得分:33)

您可以使用公用表表达式(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

这将按照Salary按降序排序后为每一行创建一个行号,然后检索第三行(包含第三高的记录)。


对于那些不想要CTE(或陷入SQL 2000)的人:

[ 注意 :这比上面的示例明显更糟糕;与exceution计划并排运行它们显示CTE的查询成本为36%,子查询的查询成本为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例确实是该例子中第三高的薪水。

答案 1 :(得分:12)

您可以使用row_number选择特定行。例如,第42个最高薪水:

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

row_number等窗口函数只能出现在selectorder by子句中。解决方法是将row_number放在子查询中。

答案 2 :(得分:6)

select MIN(salary) from (
select top 5 salary from employees order by salary desc) x

答案 3 :(得分:4)

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 where子句。然后是800,并检查大于800的工资数量,4=0 false然后工作300,最后表中共有4条记录大于300.因此4=4会遇到条款并将返回 3 C 300

答案 4 :(得分:2)

尝试一下......

use table_name
select MAX(salary)
from emp_salary
WHERE marks NOT IN (select MAX(marks)
from student_marks )

答案 5 :(得分:1)

简单的方法没有使用特定于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

首先,我们发现不同的薪水。然后我们发现不同薪水的数量大于每一行。这只不过是那个id的等级。对于最高薪水,此计数将为零。所以'+1'是从1开始排名。

现在我们可以通过在上面的查询中添加where子句来获取第N个等级的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
where rank = N;

答案 6 :(得分:1)

不要忘记使用distinct关键字: -

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

答案 7 :(得分:1)

解决方案1:这个SQL找到第N个最高工资应该适用于SQL Server,MySQL,DB2,Oracle,Teradata以及几乎任何其他RDBMS :(注意:由于子查询而性能较低)

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:使用SQL Server中的TOP关键字查找第n个最高薪水

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

解决方案3:在不使用TOP

的情况下,在SQL Server中找到第n个最高薪水
SELECT Salary FROM Employee 
ORDER BY Salary DESC OFFSET N-1 ROW(S) 
FETCH FIRST ROW ONLY

请注意,我没有亲自测试上面的SQL,我相信它只能在SQL Server 2012及更高版本中运行。

答案 8 :(得分:0)

最简单的方法是从2nd higest salary中的table获取SQL

sql> select max(sal) from emp where sal not in (select max(sal) from emp);

答案 9 :(得分:0)

SELECT * FROM 
(select distinct postalcode  from Customers order by postalcode DESC)
limit 4,1;

4这里意味着先离开4并显示下一个。

试试这个对我有用。

答案 10 :(得分:-3)

查找第n个最高薪水的非常简单的一个查询

SELECT DISTINCT(Sal) FROM emp ORDER BY Salary DESC LIMIT n,1