使用纯SQL从结果集中获取第n个最高值的最简单方法是什么?
结果集很大,因此也需要考虑性能......
答案 0 :(得分:2)
这是使用ROW_NUMBER
的T-SQL(SQL-Server 2005及更高版本)方法:
WITH CTE AS
(
SELECT
Col1, Col2, ValueCol,
RN = ROW_NUMBER() OVER (ORDER BY ValueCol DESC) -- change to ASC if you want lowest first
FROM
dbo.TableName
)
SELECT
Col1, Col2, ValueCol
FROM
CTE
WHERE
RN = @nthhighestvalue
如果您希望所有具有相同值的行都改为使用DENSE RANK
。
答案 1 :(得分:0)
首先生成有序的编号数据集,然后从中进行选择。精确的语法取决于RDBMS,但是,例如,在Oracle中,您可以执行
SELECT ROWNUM, SOMEVAL
FROM (SELECT SOMEVAL FROM SOMETABLE ORDER BY SOMEVAL DESC)
鉴于以上设定,您可以
SELECT SOMEVAL WHERE ROWNUM = :N
答案 2 :(得分:0)
在通用数据库中,您可以使用子查询和两个order by
来执行此操作。问题是top / limit / rownum语法不是标准的。在某些数据库中,您可以写:
答案 3 :(得分:0)
在Oracle中:
SELECT * FROM (
SELECT col1, ROW_NUMBER()OVER(ORDER BY col1) rnum_col1 FROM table1
) WHERE rnum_col1 = 10;
答案 4 :(得分:0)
假设您要找到第5个最高薪水,您首先按降序排列第5个不同的工资单,以便最后一个是第5个最高薪水(参见内部查询)。然后按升序重新排序并取第一个。
SELECT TOP 1 Salary FROM
(
SELECT DISTINCT TOP 5 Salary
FROM Employee
ORDER BY Salary DESC) t
ORDER BY Salary ASC
答案 5 :(得分:0)
This article深入讨论这个问题,我将从下面引用代码:
解决方案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及更高版本中运行。
解决方案4:在MySQL中运行
SELECT Salary FROM Employee
ORDER BY Salary DESC LIMIT n-1,1
LIMIT子句在该查询中接受两个参数 - 第一个参数指定要返回的第一行的偏移量,第二个参数指定要返回的最大行数。
解决方案5:适用于Oracle
select * from (
select Emp.*,
row_number() over (order by Salary DESC) rownumb
from Employee Emp
)
where rownumb = n; /*n is nth highest salary*/
解决方案6:以Oracle方式2工作
select * FROM (
select EmployeeID, Salary
,rank() over (order by Salary DESC) ranking
from Employee
)
WHERE ranking = N;
答案 6 :(得分:0)
子查询将列出最高的“ n”个最高薪水值。从该列表中,最小值将是第n个最高薪水。
`SELECT min(salary) FROM
(SELECT DISTINCT TOP n salary FROM EmployeeTable ORDER BY salary desc);`
例如:-SQL查询以查找第三高薪
`SELECT min(salary) FROM
(SELECT DISTINCT TOP 3 salary FROM EmployeeTable ORDER BY salary desc);`
答案 7 :(得分:-1)
你必须承担排序的开销,在我的例子中rownum
是排序的行号,而不是物理位置。
由于每个人都在使用分析函数来显示这是如何工作的:
select foo,bar, max(baz)
from
(
select *
from
(
select foo,bar,baz, row_number() over
(partition by some_identifier_that_Groups order by value DESC) rn
)
where rn = 1 -- get the highest value for each partition
) group by foo,bar