SELECT "goods_name", "market_price" FROM "goods" WHERE ROWNUM <= 5;
ROWNUM 详细讲解
一、ROWNUM 是什么?
ROWNUM 是 Oracle 数据库内置的伪列,不是自定义的,是数据库系统规定好的。
sql
SELECT "goods_name", "market_price"FROM "goods"WHERE ROWNUM <= 5;
含义:为查询结果中的每一行自动分配一个行号,从 1 开始,然后只返回行号 ≤ 5 的记录(即前5条)。
二、ROWNUM 的词源
| 部分 | 词源 | 含义 |
|---|---|---|
| ROW | 古英语 rāw(行、排) | 行、记录 |
| NUM | 拉丁语 numerus(数字) | 数字、编号 |
| ROWNUM | 组合词 | 行号 |
字面意思:行的编号。
三、ROWNUM 是规定好的还是自定义的?
| 对比项 | 说明 |
|---|---|
| 来源 | Oracle 数据库内置的伪列 |
| 是否自定义 | ❌ 不是,是数据库系统规定好的 |
| 能否改名 | ❌ 不能,只能用 ROWNUM |
| 是否需要定义 | ❌ 不需要,直接使用 |
MySQL 的对应物
sql
-- OracleSELECT * FROM goods WHERE ROWNUM <= 5;-- MySQLSELECT * FROM goods LIMIT 5;
| 数据库 | 限制结果数量的方式 |
|---|---|
| Oracle | WHERE ROWNUM <= n |
| MySQL | LIMIT n |
| SQL Server | SELECT TOP n |
| PostgreSQL | LIMIT n |
四、ROWNUM 的本质:伪列
什么是伪列?
伪列(Pseudo Column)是数据库中的一种特殊列:
不是真实存在的列(表中没有这个字段)
是数据库系统临时生成的
可以直接在查询中使用
Oracle 常见的伪列
| 伪列 | 含义 | 示例 |
|---|---|---|
ROWNUM | 行号(按结果顺序) | WHERE ROWNUM <= 5 |
ROWID | 行的物理地址 | SELECT ROWID, * FROM goods |
LEVEL | 层级(用于树形查询) | 递归查询中使用 |
五、ROWNUM 的执行过程
sql
SELECT goods_name, market_priceFROM goodsWHERE ROWNUM <= 5;
执行流程图
text
原表 goods ┌─────────────────────────────────────────────┐ │ goods_name │ market_price │ ├─────────────┼───────────────────────────────┤ │ 手机 │ 2999 │ │ 电脑 │ 5999 │ │ 耳机 │ 199 │ │ 键盘 │ 399 │ │ 鼠标 │ 89 │ │ 显示器 │ 1299 │ │ 音箱 │ 299 │ └─────────────┴───────────────────────────────┘ ↓ Oracle 读取数据 ↓ ┌─────────────────────────────────────────────┐ │ ROWNUM │ goods_name │ market_price │ ├─────────┼─────────────┼─────────────────────┤ │ 1 │ 手机 │ 2999 ← 符合条件 │ │ 2 │ 电脑 │ 5999 ← 符合条件 │ │ 3 │ 耳机 │ 199 ← 符合条件 │ │ 4 │ 键盘 │ 399 ← 符合条件 │ │ 5 │ 鼠标 │ 89 ← 符合条件 │ │ 6 │ 显示器 │ 1299 ← 不符合(停止)│ │ 7 │ 音箱 │ 299 ← 不再读取 │ └─────────┴─────────────┴─────────────────────┘ ↓ 返回前5条
六、ROWNUM 的重要特性
1、在 WHERE 条件之前赋值
ROWNUM 是在 WHERE 条件判断之前 就已经赋值的。
sql
-- ✅ 正确:返回前5条SELECT * FROM goods WHERE ROWNUM <= 5;-- ❌ 错误:永远返回空SELECT * FROM goods WHERE ROWNUM = 5;-- 原因:ROWNUM 从1开始,当取第1条时,1=5? 不成立,丢弃-- 第2条又变成新的第1条,永远无法达到5
2、ROWNUM 不会自动排序
sql
-- 不保证返回价格最低的5条,只返回前5条SELECT * FROM goods WHERE ROWNUM <= 5;-- 想要价格最低的5条,需要先排序SELECT * FROM (SELECT * FROM goods ORDER BY market_price) WHERE ROWNUM <= 5;
七、ROWNUM 与子查询配合
查询价格最低的5件商品
sql
-- 错误写法:ROWNUM 在排序前赋值SELECT * FROM goods WHERE ROWNUM <= 5 ORDER BY market_price; -- 先取前5条,再排序(错误!)-- 正确写法:先排序,再取前5条SELECT * FROM ( SELECT * FROM goods ORDER BY market_price) WHERE ROWNUM <= 5;
八、ROWNUM 与 ROW_NUMBER() 的区别
| 对比项 | ROWNUM | ROW_NUMBER() |
|---|---|---|
| 类型 | 伪列 | 分析函数 |
| Oracle 版本 | 所有版本 | 9i+ |
| 是否可排序 | ❌ 不能(先赋值) | ✅ 可以(OVER(ORDER BY)) |
| 语法 | WHERE ROWNUM <= 5 | ROW_NUMBER() OVER(ORDER BY id) |
sql
-- ROW_NUMBER() 更灵活SELECT * FROM ( SELECT goods_name, market_price, ROW_NUMBER() OVER(ORDER BY market_price) AS rn FROM goods) WHERE rn <= 5;
九、总结
| 问题 | 答案 |
|---|---|
ROWNUM 是什么? | Oracle 数据库的伪列,自动生成行号 |
| 是自定义的吗? | ❌ 不是,是数据库规定好的 |
| 能改名吗? | ❌ 不能,只能用 ROWNUM |
| 从几开始? | 从 1 开始 |
| 什么时候赋值? | 在 WHERE 条件判断之前 |
| 主要用途 | 限制查询结果数量(类似 MySQL 的 LIMIT) |
| 注意什么? | ROWNUM = n(n>1)永远不成立 |
一句话总结:ROWNUM 是 Oracle 数据库规定好的伪列,自动为查询结果的每一行分配行号(从1开始),WHERE ROWNUM <= 5 就是取前5条数据。它不是自定义的,而是像 SELECT、FROM 一样是数据库的内置关键字