对于Oracle的rownum问题,如果使用>、>=、=、between…and不会提示SQL语法错误,而是经常查不出一条记录来,这会出现似乎是莫名其妙的结果来,其实只要了解了这个rownum伪列的意义后就不会再感到惊奇啦!
假设有个表t_b_unit_tag,其中的一列为tagname,表中有20条记录
select rownum, tagname from t_b_unit_tag where rownum < 10 用于小于号,查出来的结果很容易理解。
如果把条件改为: rownum > 10, 这时我们一般都会想应该是表中后面10条记录,执行一下结果,怎么什么记录都没呢? 所有有必要先弄清楚rownum的用法。
rownum是对结果集加的一个伪列,即先查到结果集之后再加上去的一个列,简单的说rownum是对符合条件结果的序列号,它总是从1开始排起的。所以你选出的结果不可能没有1,而有其他大于等于1的值。
rownum > 10 没有记录,因为第一条不满足去掉的话,第二条的rownum又成了1,所以永远没有满足条件的记录。
经过两句SQL语句的比较,对rownum的概念有了一个认识,接下来,对rownum的几种现象进行分析一下:
1、select rownum, tagname from t_b_unit_tag where rownum != 10为何是返回前9条数据呢?
rownum为9后的记录的rownum为10,因条件为!=10,所以去掉,其后记录补上,rownum又是10,也去掉,如果下去也就只会显示前面9条记录了。
2 、为什么rownum > 1 时查不到一条记录,而rownum > 0 或rownum >= 1则可以显示所有的记录?
因为rownum是在查询到的结果集后加上去的,它总是从1开始。
但如果就是想用rownum > 10这种条件的话就要用嵌套语句,把rownum先生成,然后在查询,这样就可以准确的查出 >10的记录
select * from (select rownum as rn from t_b_unit_tag where rownum >= 1) where rn > 10
select rowid from t_b_unit_tag where rownum < 2
AAAdO2AAGAAAc0aAAA |
rowid的格式如下:
数据对象编号 | 文件编号 | 块编号 | 行编号 |
000000 | FFF | BBBBBB | RRR |
rowid是基于64位编码的18位字符显示(数据对象编号(6)+文件编号(3)+块编号(6)+行编号(3)),其中
A-Z <==> 0 - 25 (26) |
a-z <==> 26 - 51 (26) |
0-9 <==> 52 - 61 (10) |
+/ <==> 62 - 63 (2) |
共64位,明白这个后,就可以计算出十进制的编码值,计算公式如下:
d*(b^p)
b就是基数64,p就是从右到左,从0开始的位置数
例如:行编号AAA
0*(64^0) = 0
0*(64^1) = 0
0*(64^2) = 0
行编号 0+0+0=0
rowid是物理存在的,表示记录在表空间中的唯一位置ID,在数据库中唯一。只要记录没被移动过,rowid是不变的。rowid相对于表来说又像表中的一般列,所以rowid为清空就不会有rownum那些情况发生。