13

サブクエリに参加して、groupByのカウントの平均を取得しようとしています。それが正しい方法かどうかはわかりませんが、mysemadoc以外のサブクエリについては何もできませんでした。

シナリオ:顧客は製品ごとに平均して何件の注文をしましたか?意味:顧客が製品を注文します。そのため、顧客は特定の製品を何度も注文しました(カウント)。顧客が製品に対して行った平均注文数はいくつですか?

少し仮説的に聞こえるかもしれませんが、実際にはプロトタイプの一部にすぎませんが、Mysemaの豪華なQueryDSLを使用して、サブクエリ内に作成されたカスタム列への参照を取得する方法について疑問に思いました。

SQLでは、カウント列にエイリアスを指定し、2番目の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のような集計を行うにはどうすればよいですか(私のグループは正しいですか?)これには他のエラーがある可能性があるので、助けていただければ幸いです。

ありがとう!

編集: これは、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;
4

3 に答える 3

19

join句でサブクエリを使用することは許可されていません。JPQLでは、サブクエリはWHEREおよびHAVING部分でのみ許可されます。QuerydslJPAクエリの結合メソッドのシグネチャが広すぎます。

このクエリには2つのレベルのグループ化が必要なため、JPQL /QuerydslJPAでは表現できない可能性があります。

QuerydslJPAネイティブクエリサポートを使用してこのクエリを作成することをお勧めします。

Querydsl JPAは内部でJPQLを使用するため、JPQLの表現力によって制限されます。

于 2011-08-05T06:07:30.433 に答える
1

この質問は古く、すでに受け入れられている答えがあることを私は知っていますが、この質問から判断すると、それはまだ厄介な人のようです。同じ質問で私の答えを参照してください。セクションJoinFlagでのを使用すると、サブクエリの左結合を実現できます。これが誰かを助けることを願っています。join()Expression.path()

于 2019-04-10T07:16:36.973 に答える
1

QueryDslは結合で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();
        
于 2021-04-25T15:09:00.263 に答える