FETCH FIRST 在 Oracle 19c 中完全可用且推荐,但必须配合 ORDER BY 否则结果不可靠;分页时第一页可用 FETCH FIRST,第二页起须用 OFFSET;NULLS LAST/FIRST 应显式指定。

FETCH FIRST 在 Oracle 19c 中完全可用,且是推荐的首选方式——但必须配合 ORDER BY,否则行为不可靠。
FETCH FIRST 必须带 ORDER BY,否则可能返回任意行
Oracle 19c 虽然支持 FETCH FIRST n ROWS ONLY,但它不保证“前 n 行”是哪几行,除非显式指定排序依据。数据库底层行存储无固有顺序,不加 ORDER BY 时,每次执行结果可能不同。
- ✅ 正确写法:
SELECT * FROM employees ORDER BY employee_id FETCH FIRST 5 ROWS ONLY - ❌ 危险写法:
SELECT * FROM employees FETCH FIRST 5 ROWS ONLY(结果不可复现) - ⚠️ 注意:
NULLS LAST或NULLS FIRST应明确写出,避免NULL值被排到顶部干扰“最新/最高”语义
OFFSET + FETCH 实现分页时,OFFSET 为 0 才等价于 FETCH FIRST
分页场景下,第一页常写作 OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY,它和 FETCH FIRST 10 ROWS ONLY 效果一致;但第二页起必须用 OFFSET,不能只改 FIRST。
- 第一页(推荐简洁写法):
SELECT * FROM orders ORDER BY order_date DESC NULLS LAST FETCH FIRST 10 ROWS ONLY - 第二页(必须用 OFFSET):
SELECT * FROM orders ORDER BY order_date DESC NULLS LAST OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY - ⚠️ 错误认知:
FETCH FIRST 20 ROWS ONLY不等于“取第11–20行”,它始终是从排序后结果集开头取
与 ROWNUM 对比:FETCH FIRST 更安全,但旧脚本迁移需注意子查询结构差异
ROWNUM 写法在 19c 仍能运行,但逻辑陷阱多:它在排序前就编号,所以 <code>SELECT * FROM t ORDER BY x WHERE ROWNUM 是语法错误;正确写法必须套子查询。
-
FETCH FIRST直接跟在ORDER BY后,语义线性、不易出错 -
ROWNUM方式性能略优(尤其无排序需求时),但真实业务几乎总要排序,此时二者执行计划差异不大 - 迁移旧 SQL 时,别直接替换
WHERE ROWNUM 为 <code>FETCH FIRST 10 ROWS ONLY——必须确认外层是否有ORDER BY,否则语义已变
最易被忽略的是 WITH TIES 场景:当需要“并列第一也算进来”时,FETCH FIRST 1 ROWS WITH TIES 会返回所有与首行排序键相同的行——这在排行榜、Top N 统计中很实用,但容易被当成普通限制而漏掉测试覆盖。


















