Posted on 2012-08-23 14:37
王三 阅读(146)
评论(0) 编辑 收藏
1>:oracle中带排序的分页sql,至少包含三层,若无order by可以两层,通用模板为(hibernate也是采用这种方法):
select temp2.* from(
select rownum num,temp1.* from(
SQL查询
) temp1 where rownum<=?
)temp2 where temp2.num>?
如果是第一页的分页,可以简化为两层:
select * from(
SQL查询
) where rownum <=?
2>:有些特性需要注意:
a:最内层的sql查询中的order by项一定要保证记录的唯一性,否则,若排序字段有重复记录,则分页查询后,翻页后数据会出现重复和缺少,因为oracle没有默认排序一说,mysql的会按主键自然排序(?待确认),导致两次分页查询的order by结果不一致,哎,这样查询时非幂等的。
b:rownum是个很蛋疼的伪列,它的对满足查询条件(不包括“含有rownum的查询条件”和“排序条件”)的结果集的顺序记录,并且在生成结果集时逐一递增,也就是发现对满足查询条件(不包括“含有rownum的查询条件”和“排序条件”) 的第一条记录,rownum附加为记录上并赋值为(当前结果集的总数+1)1,然后若有rownum查询条件,则使用rownum查询条件来判断,若符合则继续查询,否则舍弃记录,然后接着查询,以此推之,那么rownum一定从1开始,所以对<、<=可以很好支持,对!=可以像<一样诡异支持,对其他的=、>、>=、between...and不为1的不支持了。
c:上面说rownum的赋值是在orderby前面的,所以若要利用好orderby,就必须使用子查询,将orderby语句放在内层无rownum的语句中。