LeetCode 176. 第二高的薪水
题目描述


题意分析
查询第二高的不同薪水。没有第二个不同值时,需要返回一行空值,而不是零行结果。
解法:SQL 查询建模
核心思路
[!blue]
排名对象是不同的薪水值,不是员工行。内层用
SELECT DISTINCT salary将相同薪水合并,再按salary DESC降序排列,此时第一行是最高薪水,第二行才是第二高的不同薪水。
OFFSET 1跳过一个不同薪水,LIMIT 1再取至多一行。如果只有一种薪水或表为空,内层便没有结果行;直接返回内层查询会得到空表,无法满足题目要求的单行NULL。将内层查询放到外层
SELECT的列位置,构成标量子查询。它有一行时取该值,没有行时取NULL;LIMIT 1保证不会出现多行。外层不依赖任何表,始终输出一行,并用SecondHighestSalary指定题目要求的列名。
解题步骤
- 去重薪水并降序排列。
- 偏移一行后只取一行。
- 外层标量查询返回它,并命名结果列。
代码实现
-- 标量子查询没有行时值为空,外层仍返回恰好一行
SELECT (
-- 薪水先去重再降序,偏移一行才是第二个不同值
SELECT DISTINCT salary
FROM Employee
ORDER BY salary DESC
LIMIT 1 OFFSET 1
) AS SecondHighestSalary;
复杂度分析
- 时间复杂度:
n为员工行数,通常需要扫描、去重与排序,可按 $O(n\log(n+1))$ 估算;索引可能减少排序,实际取决于执行计划。- 空间复杂度:去重与排序辅助空间通常为 $O(n)$ 上界,执行计划可减少使用量,结果固定一行。
关键点总结
[!green]
- 不同薪水排名与员工行号不同。
- 零行子查询作为标量时得到空值,不等于外层也没有行。
易错点总结
[!yellow]
- 不去重会把并列最高重复计为第二名。
- 直接返回内层,在没有第二名时会得到零行。
- 偏移两行会取到第三高。
相似题目
| 题目 | 难度 | 关联与区别 |
|---|---|---|
| 177. 第N高的薪水 | 中等 | 从第二高推广到第N高,仍要按不同工资值排名并处理不存在时的NULL。 |
| 178. 分数排名 | 中等 | 同样要区分不同值的排名与实际行号,重复工资不能消耗第二高的名次。 |
转载与许可
许可
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!