如何使用Spring JPA分页查询列distinct值及总数量,解决多余排序字段报错问题
问题原因
报错是因为你传入的Pageable参数中本身包含了按时间戳列U排序的规则,Spring Data JPA会自动将Pageable携带的排序条件拼接在你手写的JPQL的order by语句之后,最终生成的SQL同时包含t.C和t.U两个排序项,而SELECT DISTINCT只查询了t.C,不符合SQL语法要求。
解决方案
方案1:替换Pageable的排序规则
直接在构造分页参数时指定按C列排序,覆盖原有包含U列的排序规则,Spring就不会再额外拼接多余的排序字段:
// 手动构造仅按C列排序的分页参数,pageNum、pageSize替换为实际分页值 Pageable pageable = PageRequest.of(pageNum, pageSize, Sort.by(Sort.Direction.ASC, "C")); // 调用Repository方法 Page<String> result = yourRepository.findUniqueWithCountPagination(pageable, param);
如果分页参数是上层传入的,也可以手动替换排序部分:
Pageable sortedByCPageable = PageRequest.of( pageable.getPageNumber(), pageable.getPageSize(), Sort.by("C") );
方案2:用GROUP BY写法兼容额外排序
如果你需要保留Pageable中的U列排序规则,可以将DISTINCT改写为GROUP BY,对非分组的排序列用聚合函数包裹,完全可以实现和DISTINCT一致的取C列唯一值的效果:
@Query(value = "SELECT t.C FROM table t WHERE t.param = :param GROUP BY t.C order by t.C, MAX(t.U)", countQuery = "SELECT count(DISTINCT t.C) FROM table t WHERE t.param = :param") Page<String> findUniqueWithCountPagination(Pageable pageable, @Param("param") String param);
这里用MAX(t.U)(也可以用MIN(t.U),根据你的排序逻辑选择)包裹U列,符合分组查询的语法要求,也能保留U列的排序逻辑。
内容的提问来源于stack exchange,提问作者Aak。
相关产品推荐
相关产品推荐

