oracle相关

伪列ROWNUM

伪列就像表中的列一样,但是在表中并不存储。伪列ROWNUM是查询数据时生成,ROWNUM为结果集中每一行标识一个行号,第一行返回1,第二行返回2,但只能查询,不能进行增删改操作。
可以用来限制查询结果集中返回的行数,起到mysql中limit的作用。
SELECT ROWNUM,ENAME,JOB,SAL FROM EMP WHERE ROWNUM<=5;

使用场景1:top n

查出工资最高的前5名员工。
注意:如果要和ORDER BY一起使用的话,因为生成ROWNUM操作比排序要早,排序时已经连同ROWNUM一起排序了,所以要利用子查询查出SAL大的前5条记录:
SELECT ROWNUM,T.* FROM (SELECT ENAME,JOB,SAL FROM EMP ORDER BY SAL DESC) T WHERE ROWNUM<=5

使用场景2:分页查询

查出表EMP中第5条到第10条之间的记录。
注意:如果查询条件中直接使用ROWNUM大于或大于等于某一正整数这样的条件,不会返还任何结果,为啥?
原因是第一行读取被分配为1,rownum>1使得条件为假,接着读取第二行现在变为第一行,并还分配为1,rownum使得条件依然是假,所有行随后均未能满足该条件,所以没有行被返回。
SELECT * FROM(SELECT ROWNUM R,ENAME,JOB,SAL FROM EMP WHERE ROWNUM<=10) WHERE R>5
使用的R是内层产生的ROWNUM,在外层看来,内层查询的R是正常的一列。
如果要排序,里面还得嵌一个子查询。
SELECT * FROM(SELECT ROWNUM R,ENAME,JOB,SAL FROM (SELECT * FROM EMP ORDER BY SAL desc) WHERE ROWNUM<=10) WHERE R>5

最后格式:

SELECT * FROM   
(  
SELECT temp.*, ROWNUM RN   
FROM (SELECT * FROM 表名) temp  
WHERE ROWNUM <=end (page*pagesize)  
)  
WHERE RN >=start ((page-1)*pagesize+1)

也可使用row_number()函数实现分页查询(效率最不好)

SELECT * FROM (SELECT t.*,row_number() over(ORDER BY SAL desc) rk FROM EMP t) WHERE rk<=10 and rk>5;

伪列ROWID

伪列ROWID是插入记录时生成,它标识的是行的物理地址,确定了每条记录是在Oracle中的哪一个数据对象,数据文件、块、行上。是记录的唯一标识。当表中有大量重复数据时,可以使用ROWID快速删除重复的记录。
由 data_object_id# + rfile# + block# +row# 组成,格式如下:

 数据对象编号       文件编号       块编号           行编号
  OOOOOO            FFF            BBBBBB            RRR

使用场景1:根据字段去重

根据一个字段去重
DELETE FROM EMP E WHERE E.ROWID > (SELECT MIN(X.ROWID) FROM EMP X WHERE X.EMP_NO = E.EMP_NO);

根据a,b,c字段去重。
DELETE FROM tableA t WHERE (t.a,t.b,t.c) IN
(SELECT a,b,c FROM tableA GROUP BY a,b,c HAVING COUNT(0)>1)--查出重复的数据
AND ROWID NOT IN
(SELECT max(ROWID) FROM tableA GROUP BY a,b,c HAVING COUNT(0)>1);--保留重复数据组中的一个,也可以写成min(ROWID)

也可使用rowid实现分页查询(效率最好)

需要 ROWNUM 配合。先利用 ROWNUM 控制<=上限, 再用 ROWNUM 控制 > 下限,最后利用ROWID的唯一性
SELECT * FROM EMP WHERE ROWID IN(SELECT rid FROM (SELECT ROWNUM rn, rid FROM(SELECT ROWID rid, SAL FROM EMP ORDER BY SAL DESC) WHERE ROWNUM <= 10) WHERE rn > 5)ORDER BY SAL desc;

伪表DUAL

是为了保证在使用SELECT语句中的语句的完整性而提供的。
一般用于验证函数。例如:
select sysdate,to_char(sysdate,'yyyy-mm-dd HH24:mm:ss') from dual;

posted @ 2018-03-25 18:42  cashew  阅读(155)  评论(0编辑  收藏  举报