您的位置:首页 > 编程语言 > Java开发

rownum和rowid

2017-12-01 14:19 309 查看
区别

rownum和rowid都是伪列

rownum是根据sql查询出的结果给每行分配一个编号

rowid是物理结构上的,在每条记录insert到数据库中时,都会有一个唯一的物理记录



rownum

先看结果:

①查找前三行的数据

Select *from test where rownum<=3;

 


②查找三行以后的数据

错误:Select *from test where rownum>=3;返回为空



正解:Select *from(select rownum rn,t.* from test t)t where t.rn>=3;

 


解析:



第①种,

第一行数据rownum=1,然后发现rownum<=3满足则往下走

第二行数据rownum=2,满足继续,

第三行数据rownum=3,满足继续,

第四行数据rownum=4,不满足rownum<=3,然后将此行删除,继续

第五行数据rownum=4,关键在这里rownum还等于4,意思只要rownum不满足条件,它的值就不变,不满足rownum<=3,删除此行,继续

第六行一样,一直到了最后一行。

当然这里的删除是针对返回结果集来说的,并不是把表中的数据删除

 

第②种:

第一行数据rownum=1,不满足删除此行,继续

第二行数据依旧rownum=1,一直到最后一行,返回结果集为空

所以要借助子查询,可以这样理解子查询的查询流程要依赖上面所述的方法,然后得到查询结果附上新的rownum



在这个子查询得到的结果表中进行过滤查询,也就是主查询,而主查询就不需要再次依赖上面的方法进行,而是直接把rownum当成字段进行过滤where t.rn>=3,没有附新的rownum



所以Select *from(select rownum rn,t.* from test t)t where t.rn>=3;的结果是

 


③经典应用,分页查询

子查询用rownum查出所有的记录,然后主查询where借助子查询的rownum过滤出需要的数据(也就是第21-30条的记录,每页10条),即让rn>=21and rn<=30(主查询)

例如:
select *from (select rownum rn, s.* from student s) where rn>=21 and rn<=30
 
为什么这里必须用子查询
不用子查询,select xxx fromxxx where rownum>=3 and rownum<=7 查询结果是空。
个人理解,擦亮眼睛,有错必究:
因为此时遍历结果集中的第一行,rownum为1,不满足rownum>=3,删除结果集中的第一行,此时rownum不动,刚才的第二行数据上移,此时rownum还是1,只不过后面的数据发生了变化。如此重复,每次都删一行,直到最后一行,返回空结果集。
 
如果满足的话,就不删除本行数据,而rownum向下移动遍历下一行且rownum值要加1

举一反三:

1.Select *from test where rownum!=4;

和①效果一样

 

2.select rownum rn,t.* from test t wheret.score>=70



如上述所示,这里的rownum是对得到的结果集重新进行了编排

 

row_number () over (order by xxx)

和rownum类似只不过是多了个排序的功能,order by默认升序

按照分数排序后取出前三行的数据,这里用主查询是得不到结果的,因为如果写成这样

select uname,usex,score, row_number () over(order by score) rn from test
where rn<=3;

是不能执行的,因为rn是一个聚合函数(和rownum最大的区别),where后不能用聚合函数

所以要借助子查询:

select uname,usex,score,rn from (selectt.*,row_number () over (order by score) rnfromtest t)
where rn<=3;

 

Rowid

传统的方法:
1.        创建一个临时表用distinct把原表重复的数据过滤出去

2.        用truncate清空原表
3.        把临时表的数据重新填充到原表
但表数据是亿级的,这种方法效率就很低了

create table test_tmp as select distinct* from test;

truncatetable test;
insertinto test select * from test_tmp;
 

Rowid方法:

1.        首先子查询用group by把重复的数据分到一组
2.        然后用max或者min找出其中的一行

3.        最后主查询用rowid not in把其他行删除,任务完成

delete from stu where rowid
not in (select max(rowid)from stu t
group by t.no, t.name, t.sex);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 数据库 rownum rowid