2015-12-02 17 views
6

Tôi đang cố gắng viết một truy vấn trong QueryDSL để tìm nạp các phần tử cũ nhất của một bảng được nhóm theo parentId của chúng.QueryDSL và SubQuery với điều kiện Tuple

SQL tương đương nên là:

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 
    ) 

Bây giờ trong QueryDSL Tôi đang mắc kẹt với cú pháp.

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

Làm cách nào để bạn viết truy vấn này bằng truy vấn phụ?

Các bảng đang tìm kiếm như thế này:

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

Những gì tôi đã cố gắng cho đến nay:

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

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

và nhiều cú pháp lỗi ...

tôi sử dụng một vòng lặp bẩn, bây giờ, kể từ khi tôi đã không tìm thấy một giải pháp nào được nêu ra.

+0

Có các khóa duy nhất trong bảng con không? –

+0

Có, child.id và parent.parentId là các khóa chính tương ứng. (cảm ơn rất nhiều vì đã dành thời gian để trả lời :)) –

Trả lời

1

Trong truy vấn phụ JPA chỉ có thể xuất hiện ở phần ở đâu.

Đây là quan điểm của tôi về truy vấn của bạn

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

Cảm ơn câu trả lời. Truy vấn này không hoạt động khi số sửa đổi giống hệt nhau. Child.revision không phải là duy nhất. Không có "child2" trong truy vấn của tôi, chỉ có một phụ huynh và các con của nó. Đây là lý do tại sao tôi cần phải phù hợp với tuple, cả hai giá trị của parentId và sửa đổi trong phần Tham gia trên truy vấn –

+0

Ok, là bản sửa đổi con duy nhất trong phạm vi của một phụ huynh? Nếu không, thì điều này sẽ trả về thực sự trả lại nhiều hàng cho mỗi phụ huynh. –

+0

Tôi đã thêm một ví dụ về dữ liệu trong câu hỏi. –

1

Bạn có thể sử dụng Expressions.list() để chỉ định nhiều hơn một cột cho tại khoản:

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

Cách khác là sử dụng innerJoin(), như trong bạn SQL gốc.