【赵渝强老师】国产崖山数据库的行号:ROWNUM

YashanDB 崖山数据库 ROWNUM 伪列
YashanDB 的
ROWNUM伪列,行为高度类似 Oracle,仅单机/主备、共享集群可用;存算一体分布式集群不能使用 ROWNUM。
ROWNUM:查询返回的行,系统顺序分配编号,第一行=1,逐行递增;是先分配行号,再做过滤。
![]() |
|---|
| 点击这里查看视频讲解:【赵渝强老师】国产崖山数据库的行号:ROWNUM |
✅ 基础语法(HEAP行存表,最常用)
-- 查出前5行
SELECT t.*, ROWNUM FROM emp t WHERE ROWNUM <=5;
# 输出的信息如下:
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ROWNUM
------ ------------- ---------- ------ ------------- ------ ------ -------- -------
7369 SMITH CLERK 7902 1980/12/17 800 20 1
7499 ALLEN SALESMAN 7698 1981/2/20 1600 300 30 2
7521 WARD SALESMAN 7698 1981/2/22 1250 500 30 3
7566 JONES MANAGER 7839 1981/4/2 2975 20 4
7654 MARTIN SALESMAN 7698 1981/9/28 1250 1400 30 5
5 rows fetched.
-- 只取第1行
SELECT * FROM emp WHERE ROWNUM = 1;
# 输出的信息如下:
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ROWNUM
------ ------------- ---------- ------ ------------- ------ ------ -------- -------
7369 SMITH CLERK 7902 1980/12/17 800 20 1
-- ROWNUM>1 直接返回空!重点坑
SELECT * FROM emp WHERE ROWNUM >1; -- ❌ 无结果
# 输出的信息如下:
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ROWNUM
------ ------------- ---------- ------ ------------- ------ ------ -------- -------
原理:ROWNUM 是动态分配,必须先有 ROWNUM=1 的行满足条件,才会继续生成2、3;如果条件
ROWNUM>1,第一行ROWNUM=1不满足,直接丢弃,永远不会生成2。
✅ 排序后分页(一定要子查询!)
⚠️ 坑:
WHERE ROWNUM <=10 AND ORDER BY col,ROWNUM 在排序前分配,不是排序后的行号!
正确写法:内层先排序,外层再分配行号
select rownum,ename,sal
from (select * from emp order by sal desc)
where rownum<=5;
# 输出的信息如下:
ROWNUM ENAME SAL
------------------- --------------- ----------
1 KING 5000
2 SCOTT 3000
3 FORD 3000
4 JONES 2975
5 BLAKE 2850
✅ 分页:取第6~10行(Oracle风格分页)
SELECT * FROM (
SELECT t.*, ROWNUM rn
FROM (
SELECT * FROM emp ORDER BY sal DESC
) t
) WHERE rn >=6 AND rn <=10;
# 输出的信息如下:
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO RN
------ -------- --------- ------ ----------- ------ ------ -------- -----
7782 CLARK MANAGER 7839 1981/6/9 2450 10 6
7499 ALLEN SALESMAN 7698 1981/2/20 1600 300 30 7
7844 TURNER SALESMAN 7698 1981/9/8 1500 30 8
7934 MILLER CLERK 7782 1982/1/23 1300 10 9
7521 WARD SALESMAN 7698 1981/2/22 1250 500 30 10
5 rows fetched.
✅ 窗口函数 ROW_NUMBER()(推荐,不受ROWNUM限制)
如果需要稳定排序行号、复杂分页,优先用窗口函数 ROW_NUMBER(),分布式集群也支持:
SELECT
t.*,
ROW_NUMBER() OVER(ORDER BY sal DESC) AS rn
FROM emp t;
# 输出的信息如下:
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO RN
------ -------- ---------- ------ ------------ ------ ----- ------- -----
7839 KING PRESIDENT -1 1981/11/17 5000 10 1
7788 SCOTT ANALYST 7566 1987/4/19 3000 20 2
7902 FORD ANALYST 7566 1981/12/3 3000 20 3
7566 JONES MANAGER 7839 1981/4/2 2975 20 4
7698 BLAKE MANAGER 7839 1981/5/1 2850 30 5
7782 CLARK MANAGER 7839 1981/6/9 2450 10 6
7499 ALLEN SALESMAN 7698 1981/2/20 1600 300 30 7
7844 TURNER SALESMAN 7698 1981/9/8 1500 30 8
7934 MILLER CLERK 7782 1982/1/23 1300 10 9
7521 WARD SALESMAN 7698 1981/2/22 1250 500 30 10
7654 MARTIN SALESMAN 7698 1981/9/28 1250 1400 30 11
7876 ADAMS CLERK 7788 1987/5/23 1100 20 12
7900 JAMES CLERK 7698 1981/12/3 950 30 13
7369 SMITH CLERK 7902 1980/12/17 800 20 14
14 rows fetched.
分页示例:
SELECT * FROM (
SELECT
t.*,
ROW_NUMBER() OVER(ORDER BY sal DESC) AS rn
FROM emp t
) WHERE rn between 6 and 10;
# 输出的信息如下:
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO RN
------ ------- --------- ----- ---------- ----- ----- ------- ----
7782 CLARK MANAGER 7839 1981/6/9 2450 10 6
7499 ALLEN SALESMAN 7698 1981/2/20 1600 300 30 7
7844 TURNER SALESMAN 7698 1981/9/8 1500 30 8
7934 MILLER CLERK 7782 1982/1/23 1300 10 9
7521 WARD SALESMAN 7698 1981/2/22 1250 500 30 10
5 rows fetched.
⚠️ 列存表(COLUMN表)ROWNUM 强限制(非常重要)
列存表使用 ROWNUM 约束极多:
- ROWNUM 只能和常量比较
- WHERE里不能用
>、<、>=、<= - 等值比较只能等于常量1,
ROWNUM=2直接返回空 - 不能放在 OR 条件、不能参与运算、不能作为函数参数
- 不能在外连接的连接条件使用
👉 列存表不要用ROWNUM做分页,改用ROW_NUMBER窗口函数
✅ YashanDB 原生分页语法(推荐新写法,类似MySQL limit offset)
YashanDB 支持 FETCH / OFFSET,更简洁:
-- 取前5行
SELECT * FROM emp ORDER BY sal DESC FETCH FIRST 5 ROW ONLY;
# 输出的信息如下:
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
------- ------- ---------- ----- ------------ ------ ----- -------
7839 KING PRESIDENT -1 1981/11/17 5000 10
7902 FORD ANALYST 7566 1981/12/3 3000 20
7788 SCOTT ANALYST 7566 1987/4/19 3000 20
7566 JONES MANAGER 7839 1981/4/2 2975 20
7698 BLAKE MANAGER 7839 1981/5/1 2850 30
5 rows fetched.
-- 跳过3行,取4行(offset从0开始)
SELECT * FROM emp ORDER BY sal DESC OFFSET 3 ROW FETCH FIRST 4 ROW ONLY;
# 输出的信息如下:
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
------ ------- --------- ------ ---------- ----- ------ -------
7566 JONES MANAGER 7839 1981/4/2 2975 20
7698 BLAKE MANAGER 7839 1981/5/1 2850 30
7782 CLARK MANAGER 7839 1981/6/9 2450 10
7499 ALLEN SALESMAN 7698 1981/2/20 1600 300 30
4 rows fetched.
📌 ROWNUM常见错误汇总
WHERE ROWNUM = 2→ 空结果 ✘WHERE ROWNUM > 1→ 空结果 ✘WHERE ROWNUM <=10 ORDER BY xxx→ 行号是排序之前分配,不是排序后的行号 ✘- 分布式集群直接写ROWNUM → 语法报错 ✘
- 列存表
ROWNUM <=10→ 不支持 ✘
📌 ROWNUM vs ROW_NUMBER() vs FETCH
| 对象 | 适用场景 | 集群支持 | 说明 |
|---|---|---|---|
| ROWNUM伪列 | 单机/主备/共享集群,行存HEAP表 | ❌分布式 | 轻量取前N行;分页需要嵌套子查询 |
| ROW_NUMBER()窗口函数 | 全部部署形态,行存/列存 | ✅分布式 | 排序后生成行号,分页首选 |
| OFFSET ... FETCH | 全部部署形态 | ✅分布式 | 简洁分页,推荐新项目 |


浙公网安备 33010602011771号