【问题标题】:HQL for getting minHQL 用于获取最小值
【发布时间】:2015-12-24 05:52:10
【问题描述】:

我有以下实体:

Company.class:

public class Company {
    @JoinTable(name = "company_employee", joinColumns = @JoinColumn(name = "company_id") , inverseJoinColumns = @JoinColumn(name = "employee_id") )
    @ManyToMany(fetch = FetchType.LAZY)
    private Set<Employee> employees;

@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "company")
private List<Score> scores;

    @JoinTable(name = "company_factor", joinColumns = @JoinColumn(name = "company_id") , inverseJoinColumns = @JoinColumn(name = "factor_id") )
    @ManyToOne(fetch = FetchType.LAZY)
    private Factor factors;
}

和Employee.class

    public class Employee {
             @ManyToMany(fetch = FetchType.EAGER, mappedBy="employees")
             private Set<Company> companies;

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true, mappedBy = "company")
    private List<Score> scores;

             @JoinTable(name = "employee_factor", joinColumns = @JoinColumn(name = "employee_id") , inverseJoinColumns = @JoinColumn(name = "factor_id") )
             @ManyToMany(fetch = FetchType.LAZY)
             private Set<Factor> factors;
@Transient
    private int score;
    }

Factor.class 不包含任何关系。

另外,我有一些实体分数对于每个公司-员工组合都是唯一的。 它看起来像这样: Score.class:

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name = "company_id", insertable = false, updatable = false)
    private Company company;

    @ManyToOne(fetch=FetchType.EAGER)
    @JoinColumn(name = "employee_id", insertable = false, updatable = false)
    private Employee employee;

    @Column(name = "score")
    private BigDecimal score;

如果我得到 List,它将是 Company 和 Employee 实例的组合列表,有时 Company 或 Employee 可以重复。 目标是获取 List,按 Employee 中的 Factor 过滤,并仅显示按升序排列的每个员工的最低分数。 说,如果存在组合

employee1-company1, score=1
employee1-company2, score=2
employee2-company1, score=3
employee2-company4, score=5
employee3-company4, score6

ResultList 应该是这样的:

employee1-company1, score=1
employee2-company1, score=3
employee3-company4, score=6

所以员工不应该重复,但公司可以在列表中重复。 我不太确定,该怎么做。我所取得的是按升序显示独特的结果,但它们没有显示最低分数。我用的是 HQL:

    select distinct e from Score e 
left outer join fetch e.company 
left outer join fetch e.company.factors 
left outer join fetch e.employee 
left outer join fetch e.employee.factors ef 
where ef.factor_id=:factor_id 
group by e.employee.employee_id 
order by e.score asc

任何人都可以帮助我实现我所需要的吗?谢谢。

更新1:

我决定走另一条路。 现在我通过 Employee 使用这个查询得到它:

select distinct e from Employee e join e.scores es order by es.score asc

看来这正是我所需要的,但是如何在查询中将最小 es.score 放入Employee 对象的字段分数?也许有一些方法可以将e.score 替换为es.score

【问题讨论】:

    标签: java mysql hibernate jpa hql


    【解决方案1】:

    您可以使用以下内容:

    Select a from (Select b from Score b order by score) as a group by a.employee
    

    说明:

    • Select b from Score b order by score : 按分数的升序(默认)顺序获取结果

    • 按以上结果分组将给出唯一员工

    【讨论】:

    • 不是在 JPA 中你不能,因为你不能有子查询作为 FROM。
    • 谢谢,但是不行,说(是意外token:org.springframework.dao.InvalidDataAccessApiUsageException: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: 只是为了案例:我用在entityManager.createQuery()
    【解决方案2】:

    作为解决方案,我切换到entityManager.createNativeQuery("some native sql string")。 我对结果很满意。仅针对这种情况,有关 SQL 查询的问题是here 唯一的缺点是无法使用join fetch,因此这里出现了N+1选择问题,但我打算获取相当小的数据块,所以可以忍受。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-15
      相关资源
      最近更新 更多