oracle的sql语句的排序和分页

来源:互联网 发布:网络推广员要加班嘛 编辑:程序博客网 时间:2024/06/05 04:41

oracle与mysql不一样,在使用select查询时,oracle查询在不加order by时,查询的数据是有随机性,因此在实际应用时,获取的数据并不是一成不变的显示,这样在结合分页的话,数据显示就会不对了。可能上一页出现的数据,在翻页时,其他页也有显示。

一、排序

在使用select语句查询数据时,有时候查询出来的数据会不一样。应实际需求,一般都会在selec语句后面加上order by "字段名",因为oracle在查询并不是按照主键或有默认的排序,通过数据库查询,rowid这个是每个查询结果的唯一标识,查询时,都会生成一个rowid,根据这个rowid顺序展示数据。当然,正常在不加order by "字段名"时,也许每次查询的数据发现并没有随机,但是这个只是巧合。

如果存在查询数据需要每次都要有不同的顺序,可以select语句加上order by dbms_random.value(),这样在查询的数据每次都会不一样。这个要看实际业务需求。

二、分页

开始在使用oracle时,在应用中就遇到很奇怪的事情,一个页面展示查询的数据,支持翻页,每页展示50条数据,在我翻页时,发现下一页也出现了在上一页出现的数据,但是数据总条数是没有变的,经过排查了解,是分页查询的时候,由于查询数据没有order by 关键字,导致在查询数据出现了随机性,所以一个数据在不同的也显示。

其次oracle在实现分页的时候并不能像mysql的直接使用关键字limit就行,oracle就需要用到rownum。分页查询数据时,需要查询出rownum,通过对rownum进行分页操作。

如下:

使用select t.*,rownum from table_name查询出结果,正常的分页就是按照每页显示条数(pageSize)和当前页数(pageNum)计算分页数据,所以这里可以这样写:

select t.*,rownum from table_name where rownum >(pageSize * (pageNum - 1)) and rownum <((pageSize * (pageNum - 1) + pageSize));

但是出问题了,这样写当pageNum等于1时,可以查询出数据,更改pageNum时就查询不出来数据了,所以这样的写法是错误的。

经过修改后:

select t2.* from (select t1.*,rownum rn fromtable_name t1 where rownum < ((pageSize * (pageNum - 1) + pageSize)) t2 where rn>(pageSize * (pageNum - 1));

这样就可以实现分页查询了。

但是这里还是存在问题,就是上面说的,翻页时可能会出现重复数据。因为这里的没有使用order by 关键字,所以在oracle查询会出现随机性。因此对这个sql再修改下:

select t2.* from (select t1.*,rownum rn from (select * from table_name order by "字段名") t1

where rownum < ((pageSize * (pageNum - 1) + pageSize)) t2 where rn>(pageSize * (pageNum - 1));

这样就保证在查询数据是顺序的,然后再对顺序的数据进行分页,这样就会得到想要的结果了。

原创粉丝点击