SQL查询无效:如何获取员工表中的第二高薪资?
解决员工表第二高薪资查询问题
你的原查询语句SELECT MAX(SALARY) FROM Employee WHERE SALARY >= (SELECT MAX(SALARY) FROM Employee);逻辑错误——SALARY >= 最大薪资只会匹配到等于最高薪资的记录,所以结果必然是最高薪资,根本拿不到第二高的数据。下面给你几个适合面试场景的可行方案:
方案1:通用型写法(兼容所有支持子查询的数据库)
先排除最高薪资,再取剩下的最大值,这是最基础也最通用的写法:
SELECT MAX(SALARY) AS SecondHighestSalary FROM Employee WHERE SALARY < (SELECT MAX(SALARY) FROM Employee);
如果所有员工薪资都相同,这个查询会返回NULL,符合“不存在第二高薪资”的逻辑。
方案2:排序偏移法(适合MySQL、PostgreSQL等)
如果需要获取第二高薪资的员工完整信息,或者只想单独取薪资值,可以用去重+排序+偏移:
-- 仅获取第二高薪资值 SELECT DISTINCT SALARY AS SecondHighestSalary FROM Employee ORDER BY SALARY DESC LIMIT 1 OFFSET 1; -- 获取所有拿第二高薪资的员工信息 SELECT * FROM Employee WHERE SALARY = ( SELECT DISTINCT SALARY FROM Employee ORDER BY SALARY DESC LIMIT 1 OFFSET 1 );
如果没有第二高薪资(比如只有一种薪资),上面的查询会返回空结果。如果要返回NULL而非空集,可以用子查询包裹:
SELECT ( SELECT DISTINCT SALARY FROM Employee ORDER BY SALARY DESC LIMIT 1 OFFSET 1 ) AS SecondHighestSalary;
方案3:窗口函数法(适合PostgreSQL、SQL Server、MySQL 8.0+)
面试中用窗口函数能体现你对高级SQL的掌握,还能优雅处理薪资并列的情况:
-- 获取所有拿第二高薪资的员工信息(含并列) SELECT * FROM ( SELECT *, DENSE_RANK() OVER (ORDER BY SALARY DESC) AS salary_rank FROM Employee ) ranked_employees WHERE salary_rank = 2;
这里用DENSE_RANK()的原因是:如果有多个员工薪资并列第一,第二高的薪资排名依然是2;如果用RANK(),第二高的排名会是“第一薪资的人数+1”,你可以根据需求选择对应的窗口函数。
内容的提问来源于stack exchange,提问作者Ajju Bhai
相关产品推荐
相关产品推荐

