您能帮助我将此SQL语句转换为CriteriaBuilder语句吗?我遇到的问题是INNER JOIN语句。
SELECT th.id, th.date, th.exercise_id
FROM traininghistory th
INNER JOIN (
SELECT exercise_id, MAX(date) as maxdate
FROM traininghistory
group by exercise_id
) AS tm on tm.exercise_id = th.exercise_id AND th.date = tm.maxdate
WHERE th.accountid = :accountId
@Entity
public class TrainingHistory {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@NotNull
public Long id;
public Long accountId;
@ManyToOne
public Exercise exercise;
public Date dateDone = new Date();
public WellBeing wellBeing;
public int weight;
public int repetitions;
public int duration;
}
答案 0 :(得分:1)
通过重新构造不带INNER JOIN
的查询来找到解决方案。以下SQL查询可达到与问题中的SQL查询相同的结果,但对我而言可以转换为Criteria API。
FROM traininghistory th
WHERE th.datedone in (
SELECT MAX(tm.datedone)
FROM traininghistory tm
GROUP BY tm.exercise_id
)
AND th.accountid = :userId
因此,以此为基础,使用Criteria API的语句如下:
// define query
CriteriaBuilder cb = this.entityManager.getCriteriaBuilder();
CriteriaQuery<TrainingHistory> query = cb.createQuery(TrainingHistory.class);
Root<TrainingHistory> root = query.from(TrainingHistory.class);
query.select(root);
// define subquery
Subquery<Integer> subquery = query.subquery(Integer.class);
Root<TrainingHistory> rootSubquery = subquery.from(TrainingHistory.class);
Expression<Integer> max = cb.max(rootSubquery.get(TrainingHistory_.DATE_DONE));
subquery.select(max);
subquery.groupBy(rootSubquery.get(TrainingHistory_.exercise));
// compose whole query
query.where(
cb.and(
cb.in(root.get(TrainingHistory_.DATE_DONE)).value(subquery),
cb.equal(root.get(TrainingHistory_.ACCOUNT_ID), userId)
)
);
return this.entityManager.createQuery(query).getResultList();