分页加排序引起的数据重复问题
问题原因
排序字段有相同值的情况下,由于排序字段数据重复,可能会导致每次查询排序后结果顺序不同,分页还是会出现重复数据,这时可以加入第二个排序字段,提高排序的唯一性,最好保证排序的字段在表中的值是唯一的,这样就可以少写一个排序字段,增加查询效率,因为 order by 后面有多个排序字段时,无法用到索引。
原SQL
<select id="queryShopHotStuffList" resultType="com.zcb.scb.modules.zcb.vo.response.QueryShopStuffResponseVo"
parameterType="com.zcb.scb.modules.zcb.vo.request.QueryShopStuffRequestVo">
SELECT
t.stuff_name AS stuffName,
t.unit AS unit,
t.price AS price,
t.stuff_id AS stuffId
FROM
shop s
LEFT JOIN stuff t ON s.shop_id = t.shop_id
<where>
s.shop_id = #{shopId,jdbcType=INTEGER}
<if test="type == 1">
and t.salestatus = '上架'
</if>
and t.isdel_status = 0
</where>
GROUP BY
t.stuff_id
order by t.updatetime desc
</select>
解决方案
因为我们在使用order by 字段时,如果这个排序字段会有相同的值,这个时候与limit组合以后就会出现数据重复现象。那这是为啥呢?经过了解,这个问题是在mysql5.6以后才会出现,mysql5.5不会出现。这是由于mysql5.6做了优化,将排序方法改成了堆排序,堆排序每次请求的结果都会不一致。
这个问题我的解决方式如下:
<select id="queryShopHotStuffList" resultType="com.zcb.scb.modules.zcb.vo.response.QueryShopStuffResponseVo"
parameterType="com.zcb.scb.modules.zcb.vo.request.QueryShopStuffRequestVo">
SELECT
t.stuff_name AS stuffName,
t.unit AS unit,
t.price AS price,
t.stuff_id AS stuffId
FROM
shop s
LEFT JOIN stuff t ON s.shop_id = t.shop_id
<where>
s.shop_id = #{shopId,jdbcType=INTEGER}
<if test="type == 1">
and t.salestatus = '上架'
</if>
and t.isdel_status = 0
</where>
GROUP BY
t.stuff_id
order by t.updatetime,t.stuff_id desc
</select>
所以只要我们在回出现重复的排序字段后面在加上一个不会出现重复的字段做一个联合排序。这样就可以解决重复数据问题。