简体   繁体   English

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

[英]How do I find the nth row from a sql query?

I have a table in which data is something like this: 我有一个表格,数据是这样的:

Name    Salary
Tom      10000
John     20000
Ram      20000
Danny    15000
Sandy    14000
Riddle   15000

I can find 2nd highest salary using cte ; 我可以用cte找到第二高薪;

with cte
as
(
    select ROW_NUMBER() over (order by Salary desc) as r,
    * from Employee e
)
select * from cte where r=2

But this gives the result 'Ram' with 20000 salary. 但这给结果'Ram'带来了20000的薪水。 What I would like returned is every record for people with the nth-ranking salary. 我想要归还的是具有第n级薪水的人的每一条记录。 For instance, if I'm looking for n=2 , the result would be: 例如,如果我正在寻找n=2 ,结果将是:

Danny    15000
Riddle   15000

How do I modify the query to achieve this? 如何修改查询以实现此目的?

Use DENSE_RANK() : 使用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 SQL小提琴

Try this query: 试试这个查询:

WITH
cte AS
(select DENSE_RANK() over (ORDER BY Salary desc) AS R, e.*
from Employee e)
SELECT * From cte
WHERE R =2

Here is a SQLFiddle 这是一个SQLFiddle

I posted about this on my blog: https://fullparam.wordpress.com/2015/03/31/sql-select-nth-rank-of-something-three-approaches/ 我在我的博客上发布了这个: https//fullparam.wordpress.com/2015/03/31/sql-select-nth-rank-of-something-three-approaches/

Correlated subquery: 相关子查询:

SELECT FirstName, LastName, BaseRate
FROM DimEmployee e
WHERE (SELECT COUNT(DISTINCT BaseRate)
    FROM DimEmployee p WHERE e.BaseRate=p.BaseRate) = 4

Why is this a good answer? 为什么这是一个很好的答案? It's not really but this will work on any SQL implementation. 它不是真的,但这适用于任何SQL实现。 It's fairly slow, it will do a lot of look ups. 它相当慢,它会做很多查找。 The subquery is evaluated every time a row is processed by the outer query. 每次外部查询处理行时,都会评估子查询。 This query uses dense ranking and can return multiple rows. 此查询使用密集排名,可以返回多行。

Double Order By with TOP statement: 带有TOP声明的Double Order By:

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;

Why is this a good answer? 为什么这是一个很好的答案? Because it is an easy syntax to remember. 因为这是一个容易记住的语法。 Let's look at the subquery, which returns the N highest salaries in the DimEmployee table in descending order. 让我们看一下子查询,它以降序返回DimEmployee表中的N个最高工资。 Then, the outer query will re-order those values in ascending (default) order, this means the Nth highest salary will now be the topmost salary. 然后,外部查询将按升序(默认)顺序重新排序这些值,这意味着第N个最高薪水现在将是最高薪水。 Keep in mind that the TOP statement is MS SQL server specific. 请记住,TOP语句是特定于MS SQL服务器的。 MySQL would use LIMIT 1 for instance. MySQL会使用LIMIT 1。 In addition this solution cannot do DENSE ranking and only returns one row even if two employees share the same BaseRate. 此外,此解决方案无法执行DENSE排名,即使两名员工共享同一BaseRate,也只返回一行。

Use Windowing function: 使用窗口功能:

SELECT FirstName, LastName, BaseRate
FROM (SELECT FirstName, LastName, BaseRate, DENSE_RANK() OVER (ORDER BY BaseRate DESC) Ranking
FROM DimEmployee) AS MyTable
WHERE Ranking = 4

Why is this a good answer? 为什么这是一个很好的答案? Because it performs the best – performance is king. 因为它表现最好 - 性能是王道。 The Syntax is also ANSI SQL however of the “Big 3” only Oracle and MS are using it. 语法也是ANSI SQL,但只有Oracle和MS才使用它。 In addition you can chose to use ROW_NUMBER, DENSE_RANK or regular RANK. 此外,您可以选择使用ROW_NUMBER,DENSE_RANK或常规RANK。

The DISTINCT keyword might help you here. DISTINCT关键字可能对您有所帮助。

SELECT Salary FROM Employee order by Salary desc

will return 将返回

20000
20000
15000
15000
14000
10000

but add DISTINCT 但添加DISTINCT

SELECT DISTINCT Salary FROM Employee order by Salary desc

will return 将返回

20000
15000
14000
10000

So which do you want, the third highest person by salary (which isn't guaranteed to always be the same, as two people might share the 15,000 salary), or the people who have the third highest salary (which in this case, is only one person who has the 14,000 salary, but that's no guarantee. 你想要哪一个,按工资计算的第三高人(不保证总是相同,两个人可能分享15,000工资),或者薪水第三高的人(在这种情况下,是只有一个人有14,000工资,但这不能保证。

u can get the 2nd highest salary by using CO-RELATED Query as follows: 你可以使用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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM