2011-08-04 12 views
9

Próbuję uzyskać średnią dla liczby na grupie, łącząc się z podzapytaniem. Nie wiem, czy to właściwa droga, ale nie mogłem nic o podzapytaniach innych niż dokumentacja mysema.JPQL/QueryDSL: dołącz podzapytanie i uzyskaj kolumnę z alikwotami

Scenariusz: Ile zamówień na produkt przeciętnie zrobił klient? Znaczenie: Klient zamawia produkty. Tak więc klient zamówił określony produkt kilka razy (liczba). Jaka jest średnia liczba zamówień złożonych przez klienta na dowolny produkt?

Może brzmieć nieco hipotetycznie, w rzeczywistości jest to tylko część prototypu, ale zastanawiałem się, jak uzyskać odniesienie do niestandardowej kolumny utworzonej w podzapytaniu z fantazyjnym QueryDSL z Mysema.

W SQL wystarczy podać kolumnę zliczania jako alias i dołączyć przy użyciu drugiej kolumny identyfikatora. QueryDSL ma również metodę "as()", ale nie mam pomysłu, jak odzyskać tę kolumnę i nie widzę, jak można dołączyć do jednej kwerendy z drugą, ponieważ query.list() po prostu dostaje listę, ale dla niektórych powodem, dla którego join to akceptuje. Czuje się źle ...

Oto mój kod:

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()); 

Znowu: Jak mogę dołączyć do podzapytania? Jak uzyskać kolumnę "zliczania" aliasy, aby wykonać więcej agregacji, takich jak avg (czy moja grupa ma prawa przy okazji?) Być może mam inne błędy w tym, więc każda pomoc doceniona!

Dzięki!

Edit: To rodzaj natywnego SQL Chciałbym zobaczyć QueryDSL produktów:

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; 

Odpowiedz

11

Korzystanie podzapytania w klauzuli przyłączenia nie jest dozwolone. w JPQL podzapytania są dozwolone tylko w części WHERE i HAVING. Sygnatury metody łączenia w zapytaniach kwerendy JPA są zbyt szerokie.

Ponieważ zapytanie to wymaga dwóch poziomów grupowania, może nie można go wyrazić za pomocą JPOS/Querydsl JPA.

Proponuję napisać tę kwerendę za pomocą obsługi zapytań zapytania SQL Querydsl.

Jako, że JPQ Querydsl używa JPQL wewnętrznie, jest ograniczona przez ekspresję JPQL.

+0

Dzięki! Szkoda jednak, ponieważ zastanawiam się nad budowaniem ogólnego wyszukiwania w oparciu o QueryDSL i jakiekolwiek teoretyczne środki ograniczające, muszę pomyśleć o tym, jak włączyć alternatywne techniki do mojego znacznika wyszukiwania ... – Pete

+0

Chociaż w drugiej chwili: jak mam dostęp kolumna z aliasami()? – Pete

+0

Dla kolumny liczby aliasów użyj instancji Path (alias ścieżki, subQuery.as (alias), a następnie użyj aliasu) –