題目描述: 編寫一個 SQL 查詢,獲取 Employee 表中第二高的薪水(Salary) 。 例如上述 Employee 表,SQL查詢應該返回 200 作為第二高的薪水。如果不存在第二高的薪水,那麼查詢應返回 null。 SQL架構: 解題思路: 思路1:取第二高的薪水,可以用max()函數取 ...
題目描述:
編寫一個 SQL 查詢,獲取 Employee
表中第二高的薪水(Salary) 。
+----+--------+ | Id | Salary | +----+--------+ | 1 | 100 | | 2 | 200 | | 3 | 300 | +----+--------+
例如上述 Employee
表,SQL查詢應該返回 200
作為第二高的薪水。如果不存在第二高的薪水,那麼查詢應返回 null
。
+---------------------+ | SecondHighestSalary | +---------------------+ | 200 | +---------------------+
SQL架構:
1 Create table If Not Exists Employee (Id int, Salary int); 2 Truncate table Employee; 3 insert into Employee (Id, Salary) values ('1', '100'); 4 insert into Employee (Id, Salary) values ('2', '200'); 5 insert into Employee (Id, Salary) values ('3', '300');
解題思路:
思路1:取第二高的薪水,可以用max()函數取出最大值,然後排除這個最大值,再取一次最大值即可。但這個方案有局限性,當需要取第N名的時候,不好用。
思路2:oracle可以先使用dense_rank函數按薪水降序排名,然後取第二名去重即可。mysql沒有類似oracle的dense_rank函數,可以使用自定義變數進行排名。這個方案是根據名次去取的,要取第一名只需要改一個值即可。
解決方案一:
select max(a.salary) as SecondHighestSalary from Employee a where a.salary <> (select max(a.salary) from Employee a)
解決方案二:
oracle:
select nvl((select distinct a.salary as SecondHighestSalary from (select a.*, dense_rank() over(order by a.salary desc) as rn from Employee a) a where rn = 2), null) from dual;
mysql:
SELECT IFNULL( ( SELECT a.salary FROM ( SELECT a.salary ,@rownum :=@rownum + 1 AS rn FROM ( SELECT DISTINCT a.salary FROM Employee a ORDER BY a.salary DESC ) a,(SELECT @rownum := 0) b ) a WHERE a.rn = 2 ),NULL) as SecondHighestSalary