如何在包含SQL Server工资的表中找到第N个最高工资?
答案 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
等窗口函数只能出现在select
或order 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