You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Spring Data JPA Specification按列实现Distinct查询?

解决Spring Data JPA Specification实现PostgreSQL DISTINCT ON查询的问题

问题原因分析

你之前尝试的两种方法都没达到预期,核心是没搞懂普通DISTINCT和PostgreSQL特有的DISTINCT ON的区别:

  • query.distinct(true)是JPA标准的全局去重,只有当查询返回的所有字段完全相同时才会去重,你的两条记录title和created_at不同,所以会全部返回;
  • 第二种方法只选择了employee_id列,虽然能去重,但只返回ID,不是你需要的整条合同记录。

正确实现方式

PostgreSQL的DISTINCT ON需要指定去重列,并配合排序确保每组的第一条是最新记录。Spring Data JPA的标准Specification API不直接支持这个语法,但可以通过Hibernate的扩展API实现:

import org.hibernate.query.criteria.HibernateCriteriaBuilder;
import org.springframework.data.jpa.domain.Specification;

public class ContractSpecifications {
    public static Specification<Contract> latestByEmployeeId() {
        return (root, query, criteriaBuilder) -> {
            // 转换为Hibernate的CriteriaBuilder,支持DISTINCT ON语法
            HibernateCriteriaBuilder hibernateCb = (HibernateCriteriaBuilder) criteriaBuilder;
            
            // 指定按employee_id列去重
            query.distinctOn(hibernateCb, root.get("employeeId"));
            
            // 设置排序规则:先按employee_id分组,再按created_at降序,确保最新记录排在每组第一位
            query.orderBy(
                criteriaBuilder.asc(root.get("employeeId")),
                criteriaBuilder.desc(root.get("createdAt"))
            );
            
            return null; // 无额外过滤条件,返回null即可
        };
    }
}

代码说明

  1. 依赖Hibernate扩展:因为JPA标准API没有distinctOn方法,需要借助Hibernate的HibernateCriteriaBuilder来生成PostgreSQL特有的DISTINCT ON语法;
  2. 排序必须匹配:DISTINCT ON要求排序的第一列必须是去重列(这里是employee_id),后续排序字段(created_at DESC)用来确定每组保留哪条记录;
  3. 最终生成的SQL:这个Specification会生成和你手动写的原生SQL完全一致的语句:SELECT DISTINCT ON (employee_id) * FROM contracts ORDER BY employee_id, created_at DESC。

替代方案(如果不想依赖Hibernate API)

如果想避免和Hibernate耦合,也可以直接在Repository接口用@Query写原生SQL:

@Query(value = "SELECT DISTINCT ON (employee_id) * FROM contracts ORDER BY employee_id, created_at DESC", nativeQuery = true)
List<Contract> findLatestByEmployeeId();

内容的提问来源于stack exchange,提问作者mgh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 13:18:13