JPQL / QueryDSL: присоединиться к подзапросу и получить псевдоним столбца - PullRequest
10 голосов
/ 04 августа 2011

Я пытаюсь получить среднее значение для подсчета groupBy, присоединяясь к подзапросу. Не знаю, подходит ли это вообще, но я ничего не мог сказать о подзапросах, кроме mysema doc.

Сценарий: Сколько заказов в среднем за продукт делал клиент? Значение: Клиент заказывает продукцию. Таким образом, клиент заказывал определенный продукт несколько раз (считайте). Каково среднее количество заказов, которые заказчик сделал на любой товар?

Может показаться немного гипотетическим, на самом деле это всего лишь часть прототипа, но меня удивило, как получить ссылку на пользовательский столбец, созданный в подзапросе с причудливым QueryDSL от Mysema.

В SQL вы просто присваиваете столбцу count псевдоним и присоединяетесь, используя второй столбец 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 (кстати, моя группа права?) Возможно, у меня есть некоторые другие ошибки в этом, поэтому любая помощь приветствуется!

Спасибо!

Edit: Это родной SQL, который я хотел бы увидеть в QueryDSL:

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;

Ответы [ 2 ]

13 голосов
/ 05 августа 2011

Использование подзапросов в предложении объединения не допускается. в JPQL подзапросы разрешены только в части WHERE и HAVING. Сигнатуры методов соединения в запросах Querydsl JPA слишком широки.

Поскольку для этого запроса требуется два уровня группировки, возможно, его нельзя выразить с помощью JPQL / Querydsl JPA.

Я бы предложил написать этот запрос, используя поддержку запросов Querydsl JPA Native.

Поскольку Querydsl JPA использует JPQL для внутреннего использования, это ограничено выразительностью JPQL.

0 голосов
/ 10 апреля 2019

Я знаю, что этот вопрос старый и уже имеет принятый ответ, но, судя по этому вопросу , кажется, что все еще беспокоит парнейСмотрите мой ответ в том же вопросе.Использование JoinFlag в разделе join() и Expression.path() позволяет выполнить присоединение слева к подзапросу.Надеюсь, это кому-нибудь поможет.

...