2015-12-02 26 views
6

QueryDSLでクエリを作成しようとしていますが、parentIdでグループ化されたテーブルの最も古い要素を取得しようとしています。タプル条件付きのQueryDSLとサブクエリ

SQLに相当する必要があります:

SELECT a.* FROM child a 
    INNER JOIN 
    (
     SELECT parentId, MAX(revision) FROM child GROUP BY parentId 
    ) b 
    ON ( 
     a.parentId = b.parentId AND a.revision = b.revision 
    ) 

今QueryDSLに、私は構文でこだわっています。

JPQLQuery<Tuple> subquery = JPAExpressions 
       .select(child.parent, child.revision.max()) 
       .from(child) 
       .groupBy(child.parent); 

HibernateQuery<Child> query = new HibernateQuery<>(session); 
query.from(child) 
    .where(child.parent.eq(subquery.???).and(child.revision.eq(subquery.???)))); 

サブクエリを使用してこのクエリをどのように記述しますか?

テーブルは次のように探しています:私がこれまで試したどのような

___parent___ (not used in this query, but exists) 
parentId 
P1  | * 
P2  | * 
P3  | * 

___child___ 
parentId | revision 
P1  | 1  | * 
P1  | 2  | * 
P1  | 3  | * 
P2  | 2  | * 
P2  | 3  | * 
P3  | 1  | * 

___result from child, the highest revision for each parentId___ 
P1  | 3  | * 
P2  | 3  | * 
P3  | 1  | *

:私が使用

.where(JPAExpressions.select(child.parent,child.revision).eq(subquery)); 

-> org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected end of subtree 

、多くの構文エラー...

をまだ解決策が見つかっていないので、今は汚いループです。

+0

子テーブルに固有のキーがありますか? –

+0

はい、child.idとparent.parentIdは、それぞれの主キーです。 (ありがとう、答えに時間がかかりました:)) –

答えて

1

JPAサブクエリでは、サブクエリはwhere部分にのみ表示されます。ここで

は、クエリの私のテイクが

select(child).from(child).where(child.revision.eq(
    select(child2.revision.max()) 
.from(child2) 
.where(child2.parent.eq(child.parent)) 
.groupBy(child2.parent))).fetch() 
+0

答えをありがとう。リビジョン番号が同一の場合、このクエリは機能しません。 Child.revisionは一意ではありません。クエリには "child2"はなく、親とその子のみが存在します。これは、クエリのJoin On部分のタプル、parentIdとリビジョンの両方の値を一致させる必要がある理由です。 –

+0

Ok、親のスコープ内で一意の子リビジョンですか?そうでなければ、これは実際には親ごとに複数の行を返します。 –

+0

質問のデータの例を追加しました。 –

1

であるあなたは句でに複数の列を指定するExpressions.list()を使用することができます。

query.from(child).where(Expressions.list(child.parent, child.revision).in(subquery)); 

代替は、あなたのように、innerJoin()を使用することです元のSQL。