问题现象
今天使用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#