一、题目
编写一个 SQL 查询,获取 Employee 表中第二高的薪水(Salary) 。
+----+--------+
| Id | Salary |
+----+--------+
| 1 | 100 |
| 2 | 200 |
| 3 | 300 |
+----+--------+
例如上述 Employee 表,SQL查询应该返回 200 作为第二高的薪水。如果不存在第二高的薪水,那么查询应返回 null。
+---------------------+
| SecondHighestSalary |
+---------------------+
| 200 |
+---------------------+
二、解决
1、直觉思考
思路: 比较简单,直接看代码即可。
代码:
# Version 1
# 从排除了最大值的数据中取最大值,取得就是第二高的薪水
select max(Salary) as SecondHighestSalary from Employee
where Employee.Salary not in (select max(Salary) from Employee )
# Version 2
select max(Salary) as SecondHighestSalary from Employee
where Salary < (select max(Salary) from Employee);
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
n
)
O(n)
O(n)
2、IFNULL+LIMIT
思路: 理解不难,重要的是多写几遍。
代码:
SELECT IFNULL((
SELECT DISTINCT Salary
FROM Employee
ORDER BY Salary DESC
LIMIT 1 OFFSET 1
), NULL)
AS SecondHighestSalary;
补充:SQL中 limit 与 offset区别
limit y : 读取 y 条数据
limit x, y : 跳过 x 条数据,读取 y 条数据
limit y offset x : 跳过 x 条数据,读取 y 条数据
limit n :等价于 limit 0, n
注意:
# 不会全通过。只有一行时,可能返回空而不是null
select IFNULL(salary, NULL) as SecondHighestSalary
from Employee
group by salary
order by salary desc
limit 1, 1
# 不会全通过。只有一行时,可能返回空而不是null
SELECT distinct salary AS SecondHighestSalary
from(
select salary
, dense_rank() over(order by salary desc) as rnk
from Employee
) Employee
where rnk = 2;
# 在最外层加上IFNULL()就可以通过了。
select IFNULL((
SELECT distinct salary
from(
select salary
, dense_rank() over(order by salary desc) as rnk
from Employee
) Employee
where rnk = 2
), null) AS SecondHighestSalary;
- 解释:
- 1)行已存在,ifnull(参数0, 参数1)函数会根据参数0值进行判断后得出结果,结果有值,NULL是未知的值。
- 2)行不存在,ifnull(参数0, 参数1)函数的结果总是空,没有值。
三、参考
1、【解题】176. 第二高的薪水
2、Summary - Five ways to solve the top n/ nth problems
3、图解SQL面试题:如何查找第N高的数据?
4、176
5、mysql ifnull不起作用原因及解决方案
6、How to return NULL when result is empty?
该博客介绍了如何使用SQL查询从Employee表中获取第二高的薪水。提供了两种解决方案,包括直觉思考的简单方法和使用IFNULL与LIMIT的技巧。讨论了SQL中IFNULL函数的用法,并给出了相关参考资料。
1275

被折叠的 条评论
为什么被折叠?



