使用 oracle 的 rownum 伪列做分页查询遇到疑惑

2017-12-23 11:13:49 +08:00
 xcc7624

各位大神求帮忙啊 为什么用第二种写法分十次查出 100 条数据得出来的结果有重复的,而且就算是直接用下面的写法一次得到 100 条数据,得到结果也不一样,name 字段是没有索引的。 比如

exa_00 得到结果

exa_01 得到的结果却是

--exa_00
select * from
    (select rownum id, tb.* 
        from
        (select name from user_info order by name) tb
    )
where id> 0 and id<100;
--exa_01
select * from
    (select rownum id, tb.* from
        (select name from user_info order by name) tb
    where rownum <100)
where id >0;
1100 次点击
所在节点    数据库
7 条回复
dong3580
2017-12-23 11:20:41 +08:00
第一个先排序所有的,再从排序后取出 0 - 100 之间的,
第二个排序 0 - 100 并取出。
两个查询的范围压根不一样吧?

有几年没写 PL/SQL 了,弱弱的问一句,表一共只有 100 条数据?
xcc7624
2017-12-23 11:24:48 +08:00
@dong3580 这个一共套了三层子查询,两个 SQL 最里面的都是做的全表排序的啊,不止 100 条
bxb100
2017-12-23 11:42:52 +08:00
rownum 产生实在表记录扫描时产生,排序后进行,你可以抽出来自己看一下,rownum 是乱的. 你可以先排序,然后对结果分页
select * from ( select rownum r, t.* from (select * from user_info order by name) t where rownum <= 100) where r > 0
xcc7624
2017-12-23 11:47:20 +08:00
@bxb100 我查过 oracle 的官网 rownum 确实你说的那样,order by 的字段有没有索引对 rownum 也有影响,你的写法是我上面的第二种吧?种写法得出的结果分页查出来数据有重复的
bxb100
2017-12-23 12:13:56 +08:00
@xcc7624 恩,我理解错了,忽略我 😂
sun1991
2017-12-23 18:22:45 +08:00
第二个查询,select ... from tb, 即使 tb 本身进行了排序,也不能保证 select 结果是有序的。顺序必须用 order by 来保证,但是 order by 是在数据返回后才进行计算的。
xcc7624
2017-12-24 09:58:00 +08:00
@sun1991 在第二个里面加 order by 也不对啊

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/417014

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX