编辑:显然我之前的问题还不够,所以我将通过这次尝试使它更加清楚。
我在表中有一组行,由谓词 p1 选择,每行在 id 列中具有唯一值。 pathName 列可能包含多个具有相同值的实例。想要的是仅返回具有唯一的 pathName 且具有最高值 id 的实体。
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<TextDocument> query = builder.createQuery(TextDocument.class);
Root<TextDocument> root = query.from(TextDocument.class);
// descending ids, and group similar names together
query.orderBy(builder.desc(root.get(TextDocument_.id)));
query.groupBy(root.get(TextDocument_.pathName));
// filter
Predicate p1 = builder.equal(root.get(TextDocument_.parent), rootdoc);
Predicate p2 = builder.equal(root.get(TextDocument_.id), builder.max(root.get(TextDocument_.id)));
query.where(p1, p2);
谓词 p1 选择所有具有相同父文档的文档,并且只要它本身就可以工作。
但是,谓词 p2 是错误的。添加它会导致异常错误42903:聚合函数的无效使用。。
类似的查询问题的解决方案在SQL中显示为here,但我想使用JPA标准查询来完成。我不知道如何使嵌套的SELECT语法起作用。
为重申我自己的示例中的问题,我具有以下数据集
id parent pathName
--- ------- ---------
101 22 alpha
130 22 beta
250 22 charlie
251 22 alpha
339 22 beta
400 22 alpha
401 22 delta
正确的结果(对于parent = 22)将是:
id parent pathName
--- ------- ---------
250 22 charlie
339 22 beta
400 22 alpha
401 22 delta
有人可以帮我完成此查询吗?
答案 0 :(得分:1)
将Reza示例用于sql:
SELECT * from [tableName] t1
WHERE not exists(SELECT * from [tableName]t2 where t1.name = t2.name and t2.id > t1.id)
并假设现有的Root
Subquery<TableEntity> subQuery = criteriaQuery.subquery(TableEntity.class);
Root<TableEntity> subQueryRoot = subQuery.from(TableEntity.class);
subQuery.select(subQueryRoot)
.where(criteriaBuilder.and(
criteriaBuilder.equal(subQueryRoot.get(TableEntity_.name), root.get(TableEntity_.name)),
criteriaBuilder.greaterThan(subQueryRoot.get(TableEntity_.id), root.get(TableEntity_.id))
));
predicates.add(criteriaBuilder.not(criteriaBuilder.exists(subQuery)));
答案 1 :(得分:0)
你可以做到
SELECT * from [tableName] t1
WHERE not exists(SELECT * from [tableName]t2 where t1.name = t2.name and t2.id > t1.id)