我有一张表格,数据是这样的:
Name Salary
Tom 10000
John 20000
Ram 20000
Danny 15000
Sandy 14000
Riddle 15000
我可以使用cte
找到第二高薪;
with cte
as
(
select ROW_NUMBER() over (order by Salary desc) as r,
* from Employee e
)
select * from cte where r=2
但这会给结果'Ram'带来20000的薪水。我想要归还的是具有第n级薪水的人的每一条记录。例如,如果我正在寻找n=2
,结果将是:
Danny 15000
Riddle 15000
如何修改查询以实现此目的?
答案 0 :(得分:9)
使用DENSE_RANK()
:
;WITH cte AS
(
SELECT DENSE_RANK() OVER (ORDER BY Salary DESC) AS r, *
FROM Employee e
)
SELECT *
FROM cte
WHERE r = 2
答案 1 :(得分:1)
尝试此查询:
WITH
cte AS
(select DENSE_RANK() over (ORDER BY Salary desc) AS R, e.*
from Employee e)
SELECT * From cte
WHERE R =2
答案 2 :(得分:1)
我在我的博客上发布了这个: https://fullparam.wordpress.com/2015/03/31/sql-select-nth-rank-of-something-three-approaches/
相关子查询:
SELECT FirstName, LastName, BaseRate
FROM DimEmployee e
WHERE (SELECT COUNT(DISTINCT BaseRate)
FROM DimEmployee p WHERE e.BaseRate=p.BaseRate) = 4
为什么这是一个很好的答案?它不是真的,但这适用于任何SQL实现。 它相当慢,它会做很多查找。每次外部查询处理行时,都会评估子查询。此查询使用密集排名,可以返回多行。
Double Order By with TOP statement:
SELECT TOP 1 FirstName, LastName, BaseRate
FROM ( SELECT TOP 4 FirstName, LastName, BaseRate
FROM DimEmployee ORDER BY BaseRate DESC) AS MyTable
ORDER BY BaseRate ASC;
为什么这是一个很好的答案?因为这是一个容易记住的语法。 让我们看一下子查询,它以降序返回DimEmployee表中的N个最高工资。然后,外部查询将按升序(默认)顺序重新排序这些值,这意味着第N个最高薪水现在将是最高薪水。请记住,TOP语句是特定于MS SQL服务器的。 MySQL会使用LIMIT 1。此外,即使两名员工共享相同的BaseRate,此解决方案也无法进行DENSE排名,只返回一行。
使用窗口功能:
SELECT FirstName, LastName, BaseRate
FROM (SELECT FirstName, LastName, BaseRate, DENSE_RANK() OVER (ORDER BY BaseRate DESC) Ranking
FROM DimEmployee) AS MyTable
WHERE Ranking = 4
为什么这是一个很好的答案?因为它表现最好 - 性能是王道。语法也是ANSI SQL,但只有Oracle和MS才使用它。此外,您可以选择使用ROW_NUMBER,DENSE_RANK或常规RANK。
答案 3 :(得分:0)
DISTINCT
关键字可能会对您有所帮助。
SELECT Salary FROM Employee order by Salary desc
将返回
20000
20000
15000
15000
14000
10000
但添加DISTINCT
SELECT DISTINCT Salary FROM Employee order by Salary desc
将返回
20000
15000
14000
10000
那么你想要哪一个,按工资计算的第三高的人(不能保证总是相同的,因为两个人可能分享15,000的工资),或者是薪水第三高的人(在此案件,只有一个人有14,000工资,但这不能保证。
答案 4 :(得分:0)
您可以使用CO-RELATED Query获得第二高薪,如下所示:
select name from employee e1 --outer query
where 2= --2nd highest salary
(select COUNT(e2.salary) --inner query
from employee e2 where e2.salary >= e1.salary)