oracle进行分页查询时由order by排序引起的数据重复问题

问题现象

今天使用Spring Data中的pageable(int page,int pagesize,int sort,string sortcolumn)类进行分页查询后,发现在排序的字段sortcolumn有相同数据时,查询结果顺序会出现错乱。

原因

将查询sql打印出来后发现,pageable封装的查询语句是这种格式的

SELECT * FROM (SELECT t.*, ROWNUM AS rowno FROM ( select * from table ORDER BY sortcolumn) t WHERE ROWNUM<#endRow# ) WHERE rowno>=#startRow#

看似这个sql没什么问题,实际执行过程:

select * from table ORDER BY sortcolumn

1.首先取出table表的所有数据,并按照sortcolumn排序,这一步没问题

SELECT t.*, ROWNUM AS rowno FROM (.....) t WHERE ROWNUM<#endRow#

2.取出table表中前#endRow#个数据,问题出在这里。当endRow变化时,查出的顺序也在变。

SELECT * FROM (......) WHERE rowno>=#startRow#

3.取出从第#startRow#个数据后的所有数据。
因为第二步查询的数据顺序变化了,最后截取的数据也不一样。

解决办法

1.order by后面加上唯一性字段,比如id

SELECT * FROM (SELECT t.*, ROWNUM AS rowno FROM ( select * from table ORDER BY sortcolumn,id) t WHERE ROWNUM<#endRow# ) WHERE rowno>=#startRow#

用pageable类就是

import org.springframework.data.domain.PageRequest
val page = PageRequest(currentPage, pageSize, Sort.Direction.DESC, "sortcolumn,id")

2.手写sql,提取rownum到外部

SELECT * FROM (SELECT t.*, ROWNUM AS rowno FROM (select * from table ORDER BY LIST_ORDER) t ) WHERE rowno>=#startRow# and rowno<#endRow#
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐