查询第二高薪资SQL优化:空结果需返回NULL问题
问题描述
输入:薪资:200、300、100,对应ID:1、2、3
输出:200 [这里200是仅次于最高薪资300的数值]
我尝试了如下SQL语句:
select Case When (salary < (select max(salary) from Employee)) then salary Else NULL end as SecondHighestSalary from Employee where salary < (select max(salary) from Employee) order by salary desc limit 1;
该查询在部分场景下可得到预期结果,但当输入仅为一条薪资记录(如salary:100,id:1)时,返回空值而非预期的NULL。请求完善该SQL语句或提供优化方案。
解决方案
方案一:子查询+IFNULL 处理空集情况
原查询的问题在于当没有符合WHERE条件的记录时(比如仅一条薪资记录),会返回空结果集而非NULL。可以将查询逻辑包裹在IFNULL中,确保始终返回一行结果:
SELECT IFNULL( (SELECT DISTINCT salary FROM Employee ORDER BY salary DESC LIMIT 1 OFFSET 1), NULL ) AS SecondHighestSalary;
DISTINCT用于处理存在多个相同最高薪资的场景(比如两条薪资为300的记录,此时第二高薪资仍应为300以外的最高值)LIMIT 1 OFFSET 1表示排序后跳过第一个最高薪资,取第二个值- 若不存在第二个值,
IFNULL会返回NULL,符合需求
方案二:窗口函数实现更灵活的排名
使用DENSE_RANK()窗口函数可以更好地处理并列排名的场景,同时确保无第二高薪资时返回NULL:
SELECT MAX(salary) AS SecondHighestSalary FROM ( SELECT salary, DENSE_RANK() OVER(ORDER BY salary DESC) AS rnk FROM Employee ) t WHERE rnk = 2;
DENSE_RANK()会为相同薪资分配相同排名,避免因并列导致排名跳号- 外层通过
MAX(salary)获取排名为2的薪资最大值,若不存在排名为2的记录,MAX()会返回NULL
内容的提问来源于stack exchange,提问作者Ashiful Islam Prince
相关产品推荐
相关产品推荐

