考虑以下两个表:
项目 (id, project_name)
状态(id、id_project、status_name)
其中 Status
包含 Project
所处的所有状态。
假设我们要查询最新状态名称为“new”的所有项目。我提出的 Sql 查询是:
SELECT q.id_project FROM status q
WHERE q.status_name like 'new'
AND q.id IN (
SELECT TOP 1 sq.id from status sq
WHERE q.id_project = sq.id_project
ORDER BY sq.id DESC )
我正在尝试使用 Criteria API 复制上述查询,我注意到类 CriteriaQuery有方法 orderBy
但类 Subquery没有。
到目前为止,我提出的条件查询是:
CriteriaQuery<Project> q = criteriaBuilder.createQuery(Project.class);
Root<Status> qFrom = q.from(Status.class);
Subquery<Integer> sq = q.subquery(Integer.class);
Root<Status> sqFrom = sq.from(Status.class);
sq.select(sqFrom.get(Status_.id))
.where(criteriaBuilder.equal(sqFrom.get(Status_.project), qFrom.get(Status_.project))
我被困在这里是因为 Subquery sq
没有任何方法可以对其结果进行排序并只返回最新的结果。
为了在上述场景中获得所需的结果,有哪些替代方法可以对子查询进行排序?
最佳答案
可以使用 SELECT MAX
代替 SELECT TOP 1 ... ORDER BY ...
编写子查询:
SELECT q.id_project FROM status q
WHERE q.status_name like 'new'
AND q.id = (
SELECT MAX(sq.id) from status sq
WHERE q.id_project = sq.id_project)
这也会更快,因为与查找最大值相比,对所有记录进行排序很慢。正如已经发布的那样,它可以转换为 CriteriaQuery。
不幸的是,Criteria Queries 不支持在子查询中排序 - 请参阅以下相关答案:
https://stackoverflow.com/questions/19549616#28233425 https://stackoverflow.com/questions/5551459#5551571
如果您确实需要ORDER BY
(例如,在下面的示例中允许一定范围的值),另一种方法是使用 native 查询而不是 CriteriaQuery:
Query query = entityManager.createNativeQuery(
"SELECT bar FROM foo WHERE bar IN (SELECT TOP 10 baz FROM quux ORDER BY quuux)");
关于java - 在 JPA Criteria API 的子查询中使用 ORDER BY 的替代方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41240928/