题目描述:
编写一个 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