我有下面的查询,想将其转换为条件查询。但是,我在网上看到的大多数示例仅使用子查询中的单个选定字段。是否可以有多个选定的子查询字段?
select * from quiz q (
inner join select max_date(createdBy), completeName
from quiz
group by completeName
) latest_quiz on latest_quiz = q.createdBy and latest_quiz.completeName
是的,可以将子查询中具有多个选定字段的查询转换为 Java 中的 Criteria API 查询。在您的情况下,您希望有一个返回多列(
max_date(createdBy)
和 completeName
)的子查询,并在连接条件中使用它。
虽然 Criteria API 不像 SQL 那样直接支持多字段子查询,但您仍然可以通过使用
Expression
对象并连接这些值来实现相同的逻辑。
以下是如何使用 Criteria API 构造此查询:
假设:
Quiz
有一个createdBy
和completeName
字段。max(createdBy)
对于每个 completeName
。您可以采用以下方法:
Quiz
(外部查询)创建主查询。max(createdBy)
和 completeName
的子查询
对于每个completeName
。join
或 where
子句中使用子查询进行比较。示例代码:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Quiz> cq = cb.createQuery(Quiz.class);
Root<Quiz> quizRoot = cq.from(Quiz.class);
// Create the subquery
Subquery<Object[]> subquery = cq.subquery(Object[].class);
Root<Quiz> subqueryRoot = subquery.from(Quiz.class);
// Select the max createdBy and completeName
Expression<Date> maxCreatedBy = cb.max(subqueryRoot.get("createdBy"));
Expression<String> completeName = subqueryRoot.get("completeName");
// Group by completeName
subquery.select(cb.array(maxCreatedBy, completeName))
.groupBy(completeName);
// Join the subquery result
Join<Quiz, Object[]> subqueryJoin = quizRoot.join(subquery, JoinType.INNER);
// Use the subquery values in the join condition
cq.where(cb.equal(quizRoot.get("createdBy"), subquery.getSelection().get(0)),
cb.equal(quizRoot.get("completeName"), subquery.getSelection().get(1)));
// Execute the query
List<Quiz> results = entityManager.createQuery(cq).getResultList();
说明:
max(createdBy)
选择completeName
和cb.array()
。这允许您按 completeName
进行分组并获取每个 createdBy
的最大 completeName
。Quiz
实体)与查询的结果相连接
子查询。连接的条件基于 createdBy
和
completeName
与子查询中的值匹配的字段。where
子句确保了之间的比较
主实体和子查询的选定字段(createdBy
和
completeName
)。