oracle 伪列原理,Oracle 伪列(ROWNUM)机制

1. 概述

rownum是Oracle引入的虚列。

在物理上这个虚列并不存在,只是在查询时才构造出来。伪列通常是自由分配的,用户无法执行修改等操作。

2. 特点

关于rownum有以下主要特点:

1)rownum不属于任何表。

2)rownum存在的前提,先有结果表。

3)rownum总是从1开始。

4)rownum一般只和

5)使用rownum进行分页查询需要把rownum转化为实列,并针对rownum查询。

2. 机制原理

rownum的用法看似奇怪,其实如果明白其机制原理就会很简单。

首先我们来做个简单的实验:从dual表中取出所有的字段,并取出rownum。

如果我们采用如下的写法:t.rownum

201901a822c2eaacc9fe0f16d18b5d0a.png

这样运行就会报01747错:

b65b04776f29b5b20f79b9b4502c83d0.png

因为实际上,dual表就不存在rownum这个字段,所以我们无法使用t.rownum的格式。

正确的写法,应该是:

9385005381ff30958527e36d58d8069f.png

所以,rownum是一个虚列,不属于任何表。

那么这虚列是怎么来的。我们在做个简单的实验,便于理解:

如下,我们有一个简单的表:test_ljb,共有十条记录。

我们加上rownum。

88c013ae93fcabf1064e2001dbce20b6.png

结果如下,很好理解,选出十条记录,rownum从1到10

55c00397591637e867ab4b13c0faeeae.png

我们加上一个salary的筛选条件:

845e490198afe37a0d01618316b566a2.png

结果如下:选出三条记录,rownum从1到3

0373ca77e31dc97d72621e2e22c1ef07.png

需要注意的是,第二个结果表的rownum对应的employee和第一张并不对应。

如:在第一张表rownum为1时,对应的时Arvin,而第二张对应的是Oracle。

原因如下:

因为rownum是对结果集加的一个伪列,即先查到结果集之后再加上去的一个列。

简单的说,rownum是对符合条件结果的序列号。它总是从1开始排起的,所以选出的结果不可能跳过1,而有其他大于1的值。

或者说,rownum是一个动态的,根据新的结果集实时变化的。

比如,如下语句:

select t.*, rownum from test_ljb t where rownum >1; --大于2、3或者其他任何大于1的值,结果相同。

0ebbb9d325d0489e2fe98b847ecc7859.png

我们发现没有符合条件的记录。

根据原理,rownum是对结果集的从1开始排。那么以上的语句的结果集是什么呢?

事实上,当执行完from test_ljb时,我们可以把他当作时一个结果表,rownum是从1-10。

然后,重点,当我们执行过滤条件,rownum>1 时,第一条记录不满足,剔除。这个时候,新的结果集产生了,原来的第二条记录就成了第一条,相应的rownum变为了1-9。

再次比较原来的第一条,现在的第二条记录,他的rownum也是1,也不满足,rownum是1-8。

以此类推,流水的记录,铁打的rownum从1开始。所以,直到rownum是1,还不满足。所以最后没有记录被筛选出来,也没了rownum。

所以,我们写出的这类语句:

37935ba78d4d789ebcde4a2282c46618.png

统统都是没结果的。

不过有意思的是,选出前十条,可以有好多写法:

cf8dd45031de66eaaeb8e9e13df5f6e7.png

3. 用法

那有的同学就犯嘀咕了,我要做大于查询怎么搞啊,分页查询怎么搞啊,人家Mysql和Hive一个limit a, b 直接完事,你Oracle怎么搞。

其实方法还是有的,也是用rownum,不过要先把这货转化为实列。加个子查询就可以了。

老套路,简单实验走一波。

3.1 大于查询

还是test_ljb表,就选>5行。

3c39d0ba0af57cdd99d9a84144e29dab.png

3.2.1 简单分页查询

afafdc411832886ae76b4c2fb0c93f92.png

6d6399fe53bb2a306cbfbbc1eada2818.png

3.3.2 排序分页查询

排序分页查询就麻烦了,首先要排序,然后再排序的基础上再筛选。

当然这个也是实际项目最常用的。

选出薪水最高的第4、5、6个。

c6b743af1252b0bb53a621b81aaa0d4f.png

这里需要注意的是:rownum仅仅针对新的结果集动态标记,而排序并不会生成新的结果集,如果仅仅执行

13614ae0617ff85e39567bcf58d6ec99.png

结果如下:

151a0229a0194960f16027e76c7002e2.png

注:这里写SQL语句时,注意缩进,有利于思路流畅。

---------------------

来源:CSDN

原文:https://blog.csdn.net/qq_36743482/article/details/78919904

版权声明:本文为博主原创文章,转载请附上博文链接!

标签:ljb,记录,结果,伪列,查询,Oracle,ROWNUM,虚列,rownum

来源: https://www.cnblogs.com/LoveShare/p/14281699.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值