如何从sql查询中找到第n行?

时间:2013-08-26 17:56:57

标签: sql sql-server-2008-r2

我有一张表格,数据是这样的:

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

如何修改查询以实现此目的?

5 个答案:

答案 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

SQL Fiddle

答案 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

这是SQLFiddle

答案 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)