JPQL / QueryDSL:加入子查询并获取别名列

问题描述 投票:10回答:2

我试图通过加入子查询来获得对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;
subquery jpql querydsl
2个回答
13
投票

不允许在join子句中使用子查询。在JPQL中,子查询仅允许在WHERE和HAVING部分中。 Querydsl JPA查询中的连接方法签名太宽。

由于此查询需要两个级别的分组,可能无法用JPQL / Querydsl JPA表示。

我建议使用Querydsl JPA Native查询支持编写此查询。

由于Querydsl JPA在内部使用JPQL,因此受到JPQL的表现力的限制。


0
投票

我知道这个问题很老,已经有了一个公认的答案,但从this question来看,它似乎仍然令人不安。在同一个问题中查看我的答案。在JoinFlag部分和join()中使用Expression.path()能够实现左连接子查询。希望这有助于某人。

© www.soinside.com 2019 - 2024. All rights reserved.