实际工作中被rownum困扰了很多次,一直不明白rownum为什么只能用‘<n’ 活‘<=n’做过滤条件,今天翻书时恍然大悟,记下分享\(^o^)/
rownum的存在形式很诡异,被称作‘伪列’,它不是实际存在的列,要区别于rowid他虽然也叫伪列,但是rowid在物理地址中是实际存储并且是用来唯一标识一行记录的列,而rownum则是在内存中当你查询结果集生成后追加到结果集上的一个列,这个列从1开始递增,当你过滤掉第一条数据时rownum的编号会继续从1开始排序,强调的是在你查询结果集经过过滤读入内存后追加在结果集上的列,只要有rownum就必须有rownum=1这个值。我们结合是用例子继续理解rownum
假设有一个表tab1(a)有10条记录分别是a1,a2,a3,a4,a5,a6,a7,a8,a9,a10
1.当我要检索出前5条记录时候我可以写select a from tab1 where rownum<6;查询结果如我们所料,继续看……
2.当我们要检索后5条记录的时候可能会写 select a from tab1 where rownum>5 但是查询结果却是空集,??为什么呢,这就要考虑到他的伪列特性,在每个结果集中rownum都是从1开始取值的,我们限制了rownum>5,那么让我们虚拟一下下数据的读取顺序,首先判断第一条数据,他的rownum=1 小于5不符合条件,排除后rownum=2的记录的rownum变成了1还是小于5继续删除,逐条数据判断后结果集都被排除所以查询结果为空。
3. 为什么 between 1 and 10 或者 between 0 and 10 能查到结果,而用 between 2 and 10 却得不到结果
原因同上一样,因为 rownum 总是从 1 开始
从上可以看出,任何时候想把 rownum = 1 这条记录抛弃是不对的,它在结果集中是不可或缺的,少了rownum=1 就像空中楼阁一般不能存在,所以你的 rownum 条件要包含到 1
4.查询时使用'!='的例子:select rownum,c1 from t1 where rownum != 10 为何是返回前9条数据呢?它与 select rownum,c1 from tablename where rownum < 10 返回的结果集是一样的呢?
因为是在查询到结果集后,显示完第 9 条记录后,之后的记录也都是 != 10,或者 >=10,所以只显示前面9条记录。也可以这样理解,rownum 为9后的记录的 rownum为10,因条件为 !=10,所以去掉,其后记录补上,rownum又是10,也去掉,如果下去也就只会显示前面9条记录了
5. 为什么 rownum >1 时查不到一条记录,而 rownum >0 或 rownum >=1 却总显示所以的记录
因为 rownum 是在查询到的结果集后加上去的,它总是从1开始
6.但如果就是想要用 rownum > 7 这种条件的话话就要用嵌套语句,把 rownum 先生成,然后对他进行查询。
select *
from (selet rownum as rn,t1.* from a where ...)
where rn >7
一般代码中对结果集进行分页就是这么干的。
7.特例就是当共十条数据的时候如果要查询后五条还要用rownum时候可以使用 order by desc 然后用rownum<6就OK了。
正在痛苦的研究表空间resize中,经常被临时表空间和undo表空间无限暴涨而困扰。解决了两次,但是问题的解决过程思路不够清晰。有待研究……