[Oracle]伪列ROWID和ROWNUM

目录
1. ROWID
2. ROWNUM

ROWID

1. 是一个唯一标识一条记录的物理位置的id.
2. 没有存储在表中,可以从表中查询,但不支持插入,更新,删除它们的值。
3. 组成格式如下:
Oracle 8及以前版本:
file#+block#+row#
共占用6bytes的空间:10bit+22bit+16bit;
Oracle 8以后版本:
extend rowid:data_object_id#+rfile#+block#+row#
共占用10bytes的空间:32bit+10bit+22bit+16bit.
4. 能显示表的行是如何存储的。
5. 能以最快的方式访问表中的一行。

ROWNUM

ROWNUM是对结果集加的一个伪列,即先查到结果集,之后再加上去的一个列 (强调:先要有结果集)。简单地说 rownum 是对符合条件结果的序列号,它总是从1开始排起的,所以应用条件筛选结果时选出的结果不可能没有1而有其他大于1的值。任何时候想把 rownum = 1 这条记录抛弃是不对的,它在结果集中是不可或缺的,所以 rownum 条件要包含到 1 。

如果想获取不包含rownum = 1条件的记录,则要用嵌套语句,把 rownum 先生成,然后对它进行查询。
实现 rownum >10:
select * 
from (select rownum as rn, t1.* from t1 where ...)
where rn >10;
实现 2 < rownum < 20:
select * 
from (select rownum as rn, t1.* from t1 where ...)
where rn > 2 and rn < 20;
或者
select * from ( 
select rownum r,a from table_name 
where rownum <= 20 
order by name ) 
where r > 2; (先选再排序再选)
或者
select * from table_name 
where … 
and rownum< 20 
minus 
select * from table_name 
where … 
and rownum< 2;
注意:子查询中的rownum必须要有别名,否则还是不会查出记录来,这是因为rownum不是某个表的列,如果不起别名的话,无法知道rownum是子查询的列还是主查询的列。而且,因为rownum不是某个表的列,所以rownum不能以任何表的名称作为前缀。

rownum的应用场景:
1. 给表中某一列填充序号,比如生成主键
update table_name
set primary_column = rownum;
2. Select top n
由于oracle不支持select top语句,所以在oracle中经常是用order by跟rownum的组合来实现select top n的查询。
select col 1 ... col n from    
(select col 1 ... col n from table_name order by col 1 ... col n) 
where rownum<=n(抽出记录数) 
order by rownum asc;
注意:select * from t1 where rownum < 10 order by col1; 是先随便取10条记录,然后再order by;如果要实现"top n",即先根据某个字段排序再获取top n的记录,只能用子查询来实现先排序,后rownum;但如果在order by 的字段上加主键或索引,即可让oracle先按该字段排序,然后再rownum;
3. 限制记录返回的条数
select * from table_name where rownum < 10;
select * from table_name where rownum != 10;
效果相同,返回的都是前9条记录。
4. 获取处于指定行序号的记录,如rownum >10,2 < rownum < 20.

猜你喜欢

转载自www.cnblogs.com/jzbm/p/11722140.html