数据伪列
伪列指的是列本身不存在,但是却可以进行使用的列,在Oracle里面提供有两个非常重要的伪列:
ROWNUM、ROWID
1.行号:ROWNUM(核心)
如果在开发之中使用了ROWNUM,那么就表示会自动生成行号。
范例:观察ROWNUM使用
SELECT ROWNUM,empno,ename,job FROM emp;
ROWNUM是一个伪列,只是使用它生成行号。
ROWNUM生成的行号不是固定的,而是动态计算得来的。
范例:观察ROWNUM
SELECT ROWNUM,empno,ename,job FROM emp WHERE deptno=10;
此时行号是根据查询结果动态计算出来的,所以每一个行号都不会与特定记录捆绑。
在实际的开发过程中,ROWNUM可以做两件事情:
-
取得第一行数据:
-
取得前N行数据:
范例:查询emp表中的记录并且取得第一行数据
SELECT ROWNUM,empno,ename,job FROM emp WHERE deptno=10 AND ROWNUM=1;
SELECT ROWNUM,empno,ename,job FROM emp WHERE deptno=10 AND ROWNUM=2;
由上面可以看出,第二行查询不到任何数据
解释:为什么NOT IN 里面不能够有NULL.
NOT IN(null),如果某一列上的内容就没有null,那么就表示全部查询,但是NOT IN()本身的作用是进行数据的部分筛选,结果由于自身数据的原因,导致查询全部,那么就是灾难了(如果查询数据量大,内存将被迅速占满,整个程序就死掉了),此时就可以使用ROWNUM 来完成。
对ROWUNM而言最为重要的特性是在于它可以取得前N行记录。
范例:取得emp表的前5行记录
SELECT ROWNUM,empno,ename FROM emp WHERE ROWNUM<=5;
范例:取得6-10条记录
-
错误做法
SELECT ROWNUM,empno,ename FROM emp WHERE ROWNUM BETWEEN 6 AND 10;
在数据表的查询过程之中,ROWNUM不能够定义范围,所以此时要想正确实现所需要的功能,那么就必须利用子查询完成,在子查询中首先查询前10行记录,而后在查询后5行记录。
SELECT * FROM (SELECT ROWNUM rn,empno,ename FROM emp WHERE ROWNUM<=10)temp where temp.rn>5;
其实,上一页、下一页的程序的实现就利用了以上的查询语句。
对分页而言,往往都有一个属于自己的固定语法格式:
-
currentPage,表示的是当前所在页;
-
lineSize,表示每一页显示的数据行;
SELECT * FROM (SELECT ROWNUM RN,列,...FROM 表名称 WHERE ROWNUM<=currentPage*lineSize)temp WHERE temp.rn>(currentPage-1)*lineSzie;
范例:现在假设在第三页(currentPage=3)每页显示5行记录(lineSzie=5)
SELECT * FROM (SELECT ROWNUM rn,empno,ename FROM emp WHERE ROWNUM<=15)temp where temp.rn>10;
-
-
2.行ID:ROWID
ROWID大部分情况下是针对于一些分析上使用的,在实际开发过程中也不会感受到ROWID存在
ROWID指的是针对于每行数据提供的物理地址。
范例:查看ROWID
以“AAAR3qAAEAAAACHAAA”这个数据为例,ROWID组成:
-
数据对象编号:AAAR3q
-
数据文件编号:AAE
-
数据保存的块号:AAAACH
-
数据保存的行号:AAA
YBup-1580655083147)]
以“AAAR3qAAEAAAACHAAA”这个数据为例,ROWID组成:
-
数据对象编号:AAAR3q
-
数据文件编号:AAE
-
数据保存的块号:AAAACH
-
数据保存的行号:AAA
如果数据表中出现完全相同的数据,但是需要删除其中的冗余数据,则可以使用ROWID.