2010-10-03 143 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

相關問題