我试图通过加入子查询来获得对groupBy的计数的平均值。不知道这是否是正确的方法,但我对mysema doc以外的子查询一无所知。
方案: 客户平均每件产品订单数量是多少? 含义:客户订购产品。因此,客户多次(计数)订购了特定产品。客户为任何产品下达的平均订单数量是多少?
可能听起来有点假设,事实上它只是原型的一部分,但它让我想知道如何使用来自Mysema的花哨的QueryDSL获得在子查询中创建的自定义列的引用。
在SQL中,您只需为count列指定一个别名,然后使用第二个ID列进行连接。 QueryDSL也有“as()”方法,但我不知道,如何检索该列加上我看不出它如何与其他人加入一个查询,因为query.list()只是获取一个列表但是对于某些加入接受它的原因。感觉不对......
这是我的代码:
JPQLQuery query = createJPQLQuery();
QOrdering qOrdering = QOrdering.ordering;
QProduct qProduct = QProduct.product;
QCustomer qCustomer = QCustomer.customer;
// how many of each product did a customer order?
HibernateSubQuery subQuery = new HibernateSubQuery();
subQuery.from(qOrdering).innerJoin(qOrdering.product,qProduct).innerJoin(qOrdering.customer, qCustomer);
subQuery.groupBy(qCustomer,qProduct).list(qCustomer.id,qProduct.id,qProduct.count());
// get the average number of orders per product for each customer
query.from(qCustomer);
query.innerJoin(subQuery.list(qCustomer.id,qOrdering.count().as("count_orders")));
query.groupBy(qCustomer.id);
return (List<Object[]>) query.list(qCustomer.firstname,subQuery.count_orders.avg());
再次:我如何加入子查询? 如何获得别名“count”列以进行更多聚合,例如avg(我的团队是正确的btw?) 可能是我在这方面有其他一些错误,所以任何帮助表示赞赏!
谢谢!
修改 这就是我希望看到QueryDSL产生的原生SQL:
Select avg(numOrders) as average, cust.lastname from
customer cust
inner join
(select count(o.product_id) as numOrders, c.id as cid, p.name
from ordering o
inner join product p on o.product_id=p.id
inner join customer c on o.customer_id=c.id
group by o.customer_id, o.product_id) as numprods
on cust.id = numprods.cid
group by numprods.cid
order by cust.lastname;
答案 0 :(得分:13)
不允许在join子句中使用子查询。在JPQL中,子查询仅允许在WHERE和HAVING部分中。 Querydsl JPA查询中的连接方法签名太宽。
由于此查询需要两个级别的分组,可能无法用JPQL / Querydsl JPA表示。
我建议使用Querydsl JPA Native查询支持来编写此查询。
由于Querydsl JPA在内部使用JPQL,因此受到JPQL的表现力的限制。
答案 1 :(得分:0)
我知道这个问题很老,已经有了一个可以接受的答案,但是从this question来看,这似乎仍然令人困扰。看到我在相同问题中的答案。在JoinFlag
部分和join()
中使用Expression.path()
可以实现左连接子查询。希望这对某人有帮助。
答案 2 :(得分:0)
QueryDsl 不支持 join 中的 subQuery,但您可以通过以下方式实现:
我们希望实现以下查询:
select A.* from A join (select aid from B group by aid) b on b.aid=A.id;
将视图或 SQL 查询映射到 JPA 实体:
import lombok.Setter;
import org.hibernate.annotations.Subselect;
import org.hibernate.annotations.Synchronize;
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
@Getter
@Setter
@Subselect("select aid from B group by aid")
@Synchronize("B")
public class BGroupByAid {
@Id
private Integer aId;
}
然后在类中使用等效的 QueryDSl 实体,就像常规实体一样:
JPAQuery<QAsset> query = new JPAQuery<>(entityManager);
QBGroupByAid bGroupById = QBGroupByAid.bGroupByAid;
List<A> tupleOfAssets =
query.select(A)
.from(A).innerJoin(bGroupById).on(bGroupById.aId.eq(A.aId))
.fetchResults()
.getResults();