2015-12-02 27 views
6

QueryDSL'de, bir tablonun en eski öğelerini parentId'ye göre gruplandırmak için bir sorgu yazmaya çalışıyorum.QueryDSL ve Tuple koşulu ile SubQuery

SQL eşdeğeri olmalıdır:

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 
    ) 

Şimdi QueryDSL ben sözdizimi ile sıkışıp kaldım.

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.???)))); 

Bu sorguyu bir alt sorgu kullanarak nasıl yazıyorsunuz?

tablolar böyle arıyoruz:

___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  | *

şimdiye kadar denedim Ne:

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

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

ve birçok sözdizimi hatalarını ...

kullandığım şimdilik kirli bir döngü, henüz bir çözüm bulamadım.

+0

Alt tablodaki benzersiz anahtarlar var mı? –

+0

Evet, child.id ve parent.parentId ilgili birincil anahtarlardır. (cevap vermek için zaman ayırdığınız için çok teşekkürler :)) –

cevap

1

JPA alt sorgularında yalnızca bölümün içinde görünebilir. İşte

Sen fıkrada için birden fazla sütunu belirtmek için Expressions.list() kullanabilirsiniz Sorgunuzun

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

Cevabınız için teşekkürler. Düzeltme numaraları aynı olduğunda bu sorgu çalışmaz. Child.revision benzersiz değildir. Sorgumda "child2" yok, sadece bir ebeveyn ve onun çocukları var. Bu nedenle, tuple eşleşmesi gerekiyor, her iki değer de parentId ve revizyon –

+0

Sor bölümünün birleşiminde, bir ebeveynin kapsamında benzersiz bir çocuk revizyonu mu? Değilse, bu geri dönecektir gerçekten ebeveyn başına birden çok satır döndürür. –

+0

Sorudaki verilere bir örnek ekledim. –

1

almak benim geçerli:

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

olduğu gibi innerJoin() kullanmak sizin orijinal SQL