首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >jpa criteria-api:使用子选择连接

jpa criteria-api:使用子选择连接
EN

Stack Overflow用户
提问于 2014-12-17 00:27:53
回答 1查看 2.5K关注 0票数 11

此查询用于检索一对多关系中的最后一条记录(请参见SQL join: selecting the last records in a one-to-many relationship)

代码语言:javascript
复制
SELECT  p.*
FROM    customer c 
        INNER JOIN (
                      SELECT customer_id, MAX(date) MaxDate
                      FROM purchase
                      GROUP BY customer_id
                    ) MaxDates ON c.id = MaxDates.customer_id 
        INNER JOIN purchase p ON MaxDates.customer_id = p.customer_id
                    AND MaxDates.MaxDate = p.date;

我的问题是:如何通过带有jpa criteria-api的subselect构建此连接?有可能吗?如果不是,可以使用jpql吗?

到目前为止我的代码如下:

代码语言:javascript
复制
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
final CriteriaQuery<Purchase> query = cb.createQuery(Purchase.class);
final Root<CustomerEntity> root = query.from(Customer.class);

// here should come the join with the sub-select

final Path<Purchase> path = root.join(Customer_.purchases);
query.select(path);

final TypedQuery<Purchase> typedQuery = entityManager.createQuery(query);
return typedQuery.getResultList();
EN

回答 1

Stack Overflow用户

发布于 2020-08-28 00:45:45

使用JPA2.0不能实现这样的查询,但是我们可以通过重构查询来解决它

代码语言:javascript
复制
SELECT  p.*
FROM    customer c 
        /* This part gets the maximum date of a customer purchase
           We will replace it with a subquery in the where
        INNER JOIN (
                      SELECT customer_id, MAX(date) MaxDate
                      FROM purchase
                      GROUP BY customer_id
                    ) MaxDates ON c.id = MaxDates.customer_id */
        /* This part crosses the maximum date of a customer with the purchase itself to obtain the information
        INNER JOIN purchase p ON MaxDates.customer_id = p.customer_id
                    AND MaxDates.MaxDate = p.date*/
-- We make the crossing with the purchase (there will be N tickets per customer, with N being the number of purchases)
INNER JOIN purchase p on p.customer_id = c.id
-- In the where clause we add a condition so that these N entries become that of the     maximum date
WHERE p.date = (
    SELECT MAX(p2.date)
    FROM purchase p2
    WHERE p2.customer_id = c.id)
;

使用criteria-api的实现如下所示

代码语言:javascript
复制
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Purchase> query = cb.createQuery(Purchase.class);
Root<Customer> root = query.from(Customer.class);
Join<Customer,Purchase> join = root.join(root.get("purchases"),JoinType.INNER);

Subquery<Date> sqMaxdate = cq.subquery();
Root<Purchase> sqRoot = sqMaxDate.from(Purchase.class);
Join<Purchase,Consumer> sqJoin = sqRoot.join(sqRoot.get("customer"),JoinType.INNER)
sqMaxDate.select(cb.max(sqRoot.get("date")));
sqMaxDate.where(cb.equal(sqJoin.get("id"),root.get("id")));

query.where(cb.equal(join.get("date"),sqMaxDate.getSelection()));
query.select(join);

TypedQuery<Purchase> typedQuery = entityManager.createQuery(query);
return typedQuery.getResultList();
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27509322

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档