rownum 表示行号,实际上此是一个列,但是这个列是一个伪列,此列可以在每张表中出现。
rowid 表示每一列对应的十六进制物理地址值
select e.*,rownum rn,rowid ri from emp e;
sq查询语句运行顺序
1.找到员工表中工资最高的三名员工,看第一段代码
select * from (select ename,job,sal,rownum rn from emp order by sal desc) e where e.rn<4;
会发现我们排序后取出来的结果并不是工资最高的员工
2.分页显示数据,每页5条数据,查第二页数据
select e.*,rownum from emp e where rownum<=10 and rownum>5; 会报错
根据sql语句的运行顺序,我们就很好解释这两个问题出现的原因了,第一个语句子查询语句先运行select后运行order by,所以行号是按开始的顺序排列的.
第二个语句先运行where条件,rownum是从1开始所以,>5永远为假
关于第一个问题最简单写法
select * from (select * from emp order by sal desc) where rownum<4; rownum是伪列在每张表中出现,所以可以直接使用;
第二个问题写法
select * from (select e.*, rownum rn from emp e) p where p.rn<=10 and p.rn>5;
3.对比一些代码,更多的了解一下rownum
select rownum from emp; 不报错
select e.rownum from emp e; 报错
emp表中没有rownum这一列,rownum只是一个伪列,每一张表中都有,但又不实际存在,所以可以直接查询,而不可以用表点查询
select e.*,rownum from emp e; 不报错
select *,rownum from emp; 报错
这个疑问是一个美女给我解答的,她说*已经代表所有,后面不能再加字段,会出现语法错误,表点星是代表这个表的所有列,后面可以再跟其他的字段
select * from (select ename,job,sal,rownum from emp order by sal desc) where rownum<5; 可以先猜想一下这个运行结果是什么
select * from (select ename,job,sal ,rownum from emp) p where p.rownum<5; 先猜想一下这个运行会不会报错.
上面两个问题第一个你会发现取出来的结果是工资最高的前四名员工,可以考虑一下原因,判断条件的rownum是属于哪张表的rownum.
第二个问题会报错,报错原因是字段重复或者说不知道去查询哪个字段,p.rownum在一些人认为中是p表的rownum列,但其实p表还有一个伪列rownum.所以会造成冲突,解决办法就是用别名.