Oracle数据库查询employees表第3高薪资返回0条记录求助
解决Oracle查询第3高薪资返回0条记录的问题
嘿,我来帮你搞定这个Oracle查询的问题!首先得说清楚你原语句为啥会返回空——这是Oracle里ROWNUM的特性导致的!Oracle的ROWNUM是先筛选再编号的:当你在外层直接写WHERE ROWNUM = 3时,数据库会先尝试找第一条符合条件的记录,给它标上ROWNUM=1,但这条不满足=3就被过滤掉;接着第二条记录进来,ROWNUM还是会从头标成1,同样不满足,以此类推,最后自然啥也查不到。
那怎么改呢?核心思路是先给排序后的薪资分配好行号,再在外层筛选行号等于3的记录,而且要给ROWNUM起一个别名,让数据库先完成编号再筛选。
修正后的基础查询语句
SELECT salary AS third_highest_salary FROM ( SELECT salary, ROWNUM AS rn FROM ( SELECT DISTINCT salary FROM employees ORDER BY salary DESC ) -- 先取前3条,提升查询效率,可选但推荐加上 WHERE ROWNUM <= 3 ) WHERE rn = 3;
处理边界情况:如果没有第3高薪资
上面的语句如果员工薪资种类不足3种(比如只有2种不同薪资),还是会返回0条记录。如果希望这种情况返回NULL而不是空结果,可以结合NVL和NOT EXISTS处理,或者用更简洁的分析函数写法:
方式1:用ROW_NUMBER()分析函数(逻辑更清晰)
SELECT NVL(salary, NULL) AS third_highest_salary FROM ( SELECT salary, ROW_NUMBER() OVER (ORDER BY salary DESC) AS rn FROM (SELECT DISTINCT salary FROM employees) ) WHERE rn = 3;
ROW_NUMBER()会直接给去重后的薪资按降序分配行号,筛选行号为3的记录即可。如果没有第3条结果,会返回空,结合NVL可以明确返回NULL。
方式2:兼容低版本的兜底写法
SELECT NVL(third_highest_salary, NULL) AS third_highest_salary FROM ( SELECT salary AS third_highest_salary, ROWNUM AS rn FROM ( SELECT DISTINCT salary FROM employees ORDER BY salary DESC ) WHERE ROWNUM <= 3 ) WHERE rn = 3 UNION ALL SELECT NULL FROM dual WHERE NOT EXISTS ( SELECT 1 FROM (SELECT DISTINCT salary FROM employees) WHERE ROWNUM <= 3 );
你可以分步执行内层查询,先看去重后的薪资排序结果,再看中间层的行号分配,最后外层筛选,就能明确每一步的结果是否符合预期啦~
内容的提问来源于stack exchange,提问作者Bro
相关产品推荐
相关产品推荐

