Oracle查询问题:如何结合rownum与distinct获取第二行数据
解决Oracle中获取排序后第二行数据的问题
我来帮你搞定这个查询问题——你遇到的是Oracle rownum的经典使用陷阱,先给你拆解原因,再给你两种可行的解决方案:
为什么你的原语句不生效?
Oracle的rownum是在结果行被返回时才逐行分配编号的,它从1开始,只有当rownum=1的行被选中后,才会给下一行分配rownum=2。你原来的语句直接在外层筛选r_=2,相当于先过滤掉了rownum=1的行,剩下的行根本不会被分配rownum=2,所以永远查不到结果。
解决方案1:嵌套三层子查询(兼容所有Oracle版本)
我们需要多套一层子查询,先让内层给所有排序后的行分配好rownum,再在外层筛选目标行:
SELECT run_date FROM ( SELECT inner_run.run_date, rownum r_ FROM ( SELECT DISTINCT run_date FROM transactions WHERE primary_customer_id = 'cliente' GROUP BY run_date ORDER BY run_date DESC ) inner_run ) WHERE r_ = 2;
解决方案2:使用Oracle 12c+的OFFSET/FETCH语法(更简洁)
如果你的Oracle版本是12c或以上,推荐用这种更直观的写法:跳过第一行,只取接下来的一行数据:
SELECT DISTINCT run_date FROM transactions WHERE primary_customer_id = 'cliente' GROUP BY run_date ORDER BY run_date DESC OFFSET 1 ROW FETCH NEXT 1 ROW ONLY;
额外优化建议
你的内层查询里SELECT DISTINCT和GROUP BY run_date是重复操作——GROUP BY run_date已经会返回唯一的run_date值了,完全可以去掉DISTINCT简化查询,两种方案都适用:
-- 简化后的内层查询 SELECT run_date FROM transactions WHERE primary_customer_id = 'cliente' GROUP BY run_date ORDER BY run_date DESC
内容的提问来源于stack exchange,提问作者Pedro Plaza Garcia




