题目描述

✅ 176. 第二高的薪水

image-20260928230906330

image-20260928230906331

题意分析

查询第二高的不同薪水。没有第二个不同值时,需要返回一行空值,而不是零行结果。

解法: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. 分数排名 中等 同样要区分不同值的排名与实际行号,重复工资不能消耗第二高的名次。
转载与许可
作者
链接 https://hgnulb.github.io/blog/2023/52158541
许可 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!