2010-10-03 141 views

回答

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 

这将创建于各行的行号已经被排序之后按降序工资,然后检索第三行(其中包含第三高的记录)。


对于那些你们谁不想要一个CTE(或者是停留在SQL 2000):

[:这个执行noticably比上面的例子更糟;运行它们并排侧与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个薪水(在这种情况下,我们会说),并按最高薪水排序。

如果我们希望看到第三高的薪水,子查询将返回:

Salary 
----------- 
80,000 
72,000 
50,000 

外部查询,然后选择从子查询中的第一份工资,除了我们的排序是升序这个时候,这从小到大排序,所以50,000是第一个排序升序的记录。

正如你所看到的,在这个例子中,50,000确实是第三高薪水。

+0

这部分我不清楚ü可以解释给我SalarySubquery ORDER BY工资ASC – NoviceToDotNet 2010-10-22 19:32:13

+0

@NoviceToDotNet - 我根据您的意见编辑了我的答案 - 我希望他们能够清理一些问题。 – LittleBobbyTables 2010-10-22 20:09:53

+0

@LittleBobbyTables:我编辑了你的答案 - CTE部分。如果它是正确的,请接受更改,否则,纠正我。 – 2014-09-11 17:50:40

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窗函数只能出现在selectorder by子句。解决方法是将row_number放入子查询中。

6
select MIN(salary) from (
select top 5 salary from employees order by salary desc) x 
+0

我认为它最简单。做得好!! – himanshupareek66 2016-05-12 09:06:41

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 

首先我们找出不同的薪水。然后我们发现不同薪水的薪水大于每一行。这不过是该身份证的等级。对于最高工资,此计数将为零。因此“+1”是为了从1

开始排名现在我们可以通过添加得到于第N个等级标识WHERE子句上面的查询。

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; 
2

尝试...

use table_name 
select MAX(salary) 
from emp_salary 
WHERE marks NOT IN (select MAX(marks) 
from student_marks) 
-3

很简单的查询找到第n个最高工资

SELECT DISTINCT(Sal) FROM emp ORDER BY Salary DESC LIMIT n,1 
+1

这被标记为** [sql-server] **; SQL Server没有LIMIT关键字 – LittleBobbyTables 2013-04-25 15:29:21

0

最简单的方法是在SQLtable得到2nd higest salary

sql> select max(sal) from emp where sal not in (select max(sal) from emp); 
1

不要忘记使用distinct关键字: -

SELECT TOP 1 Salary 
FROM 
(
    SELECT Distinct TOP N Salary 
    FROM Salaries 
    ORDER BY Salary DESC 
) SalarySubquery 
ORDER BY Salary ASC 
2
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假更大的编号,然后为300的工作,最后总共有4个表中的记录其中大于300。因此4=4将满足where子句,并返回 3 C 300

0

解决方案1:此SQL找到第N个最高的薪水在SQL Server,MySQL和DB2,甲骨文,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:使用TOP关键字在SQL Server中找到的第n个薪水最高

SELECT TOP 1 Salary 
FROM (
     SELECT DISTINCT TOP N Salary 
     FROM Employee 
     ORDER BY Salary DESC 
    ) AS Emp 
ORDER BY Salary 

解决方案3:查找SQL Server中的第n最高的薪水,而无需使用TOP

SELECT Salary FROM Employee 
ORDER BY Salary DESC OFFSET N-1 ROW(S) 
FETCH FIRST ROW ONLY 

请注意,我没有亲自测试过上面的SQL,我相信它只能在SQL Server 2012及更高版本中运行。

0
SELECT * FROM 
(select distinct postalcode from Customers order by postalcode DESC) 
limit 4,1; 

4在这里是指离开前4并显示下一个1

试试这个工作对我来说。

+0

Postalcode这里是列名,Customers是表名。 – 2018-03-07 13:27:15

相关问题