考虑以下两个表:
Project ( id, project_name)
Status ( id, id_project, status_name)
Where 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 复制上述查询,我注意到该类标准查询 http://docs.oracle.com/javaee/6/api/javax/persistence/criteria/CriteriaQuery.html有方法orderBy
但班级Subquery http://docs.oracle.com/javaee/6/api/javax/persistence/criteria/Subquery.html没有。
到目前为止我提出的条件查询是:
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。
不幸的是,条件查询不支持子查询中的排序 - 请参阅以下相关答案:
https://stackoverflow.com/questions/19549616#28233425 https://stackoverflow.com/questions/19549616#28233425
https://stackoverflow.com/questions/5551459#5551571 https://stackoverflow.com/questions/5551459#5551571
另一种选择,如果您really需要一个ORDER BY
(例如,在下面的示例中允许一定范围的值)是使用本机查询而不是 CriteriaQuery:
Query query = entityManager.createNativeQuery(
"SELECT bar FROM foo WHERE bar IN (SELECT TOP 10 baz FROM quux ORDER BY quuux)");
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)