[英]Use Hibernate Criteria API to return first row of each group
我是Hibernate的新手,我正在嘗試編寫一個條件查詢來返回給定日期員工的最新狀態
id | Status | status_date
1 | Active | 1/10/2017
2 | Active | 1/10/2017
...
1 | Inactive| 5/10/2017
...
1 | Active | 9/10/2017
所以我將日期傳遞給查詢,並希望找到該日期每位員工的最新狀態。預期結果將是這樣的
示例:對於日期6/1/2017,這將是返回的數據
id | Status | Date
1 | Inactive| 5/10/2017
2 | Active | 1/10/2017
我能夠使用id添加group by,並按狀態日期按降序排列行。 有沒有辦法可以只選擇每組的頂行? 我嘗試在status_date上使用max函數,但這不起作用。
CriteriaBuilder builder = this.entityManager.getCriteriaBuilder();
CriteriaQuery<Employee> cq = builder.createQuery(Employee);
Root<Employee> root = cq.from(Employee.class);
cq.select(root);
cq.groupBy(root.get("id"));
cq.orderBy(builder.desc(root.get("status_date")));
cq.having(builder.max(root.get("status_date")));
由於您希望輸出聚合,因此不要將聚合用作條件,因此不應將其放在having
子句中。 您必須將聚合添加到選擇列表中。
首先,您必須創建聚合結果類(通常與您的實體類不同):
public static class StatusEntityResult {
private String userId;
private String status;
private Date statusDate;
// getter, setter, constructor with all parameters here
}
然后使用它作為結果創建一個查詢:
public List<StatusEntityResult> queryStatus() throws ParseException {
// Date condition
Date targetDate = new SimpleDateFormat("yyyy-MM-dd").parse("2017-10-06");
CriteriaBuilder builder = this.entityManager.getCriteriaBuilder();
// Use StatusEntityResult as result
CriteriaQuery<StatusEntityResult> cq = builder.createQuery(StatusEntityResult.class);
Root<Employee> root = cq.from(Employee.class);
// Select `id`, `status` and `max(status_date)`
cq.multiselect(root.get("id"), root.get("status"), builder.max(root.get("statusDate")))
.where(builder.lessThanOrEqualTo(root.get("statusDate"), targetDate))
.groupBy(root.get("id"))
.orderBy(builder.desc(root.get("statusDate")));
return this.entityManager.createQuery(cq).getResultList();
}
結果是:
邊注
根據您的編寫,您試圖使用JPA Criteria
,而不是Hibernate Criteria
。 對於Hibernate Criteria
解決方案,您可以嘗試閱讀@default locale
建議
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.