Несколько агрегатов с использованием JPA в одном запросе - PullRequest
0 голосов
/ 03 мая 2018

У меня есть таблица для хранения элементов, и мне нужно выбрать агрегированные данные на основе нескольких фильтров.

CREATE TABLE Parents(id int, name varchar)
CREATE TABLE Items(id int, parent_id int, field_A int,field_B int)

Теперь я хочу подсчитать предметы, где field_A = 1, а также я хочу подсчитать предметы, где field_A = 1 и field_B = 2 для всех родителей.

SELECT p.id, p.name, count1, count2 FROM Parents p
INNER JOIN 
(SELECT count(id) as count1, parent_id FROM Items WHERE field_A=1 GROUP BY 
parent_id) select1 ON select1.parent_id=p.id
INNER JOIN 
(SELECT count(id) as count2, parent_id FROM Items WHERE field_A=1 AND 
field_B=2 GROUP BY parent_id)
select2 ON select2.parent_id=p.id

Каков будет правильный способ реализовать это, используя JPA как часть приложения JEE? В моем понимании подзапросы не поддерживаются в JPA, и я должен использовать собственные запросы. Некоторые тестовые данные:

insert into items(id,parent_id, field_A, field_B) values(1,1,1,1);
insert into items(id,parent_id, field_A, field_B) values(2,1,1,2);
insert into items(id,parent_id, field_A, field_B) values(3,1,2,1);
insert into items(id,parent_id, field_A, field_B) values(4,1,2,2);
insert into items(id,parent_id, field_A, field_B) values(5,2,1,2);
insert into items(id,parent_id, field_A, field_B) values(6,2,1,3);
insert into items(id,parent_id, field_A, field_B) values(7,1,1,3);
insert into items(id,parent_id, field_A, field_B) values(8,2,1,2);
insert into items(id,parent_id, field_A, field_B) values(9,2,1,2);

1 Ответ

0 голосов
/ 03 мая 2018

тьфу, включается с подзапросами. Позвольте мне сначала упростить ваш SQL:

SELECT 
    p.id, 
    p.name,
    SUM(1) AS count1, 
    SUM(CASE i.field_B WHEN 2 THEN 1 ELSE 0 END) AS count2
FROM Items i
JOIN Parents p ON i.parent_id = p.id
WHERE i.field_A = 1
GROUP BY p.id, p.name

Ваш JPQL становится:

SELECT
    p.id,
    p.name,
    SUM(1),
    SUM(CASE WHEN i.fieldB = 2 THEN 1 ELSE 0 END)
FROM Items i
JOIN i.parent p
WHERE i.fieldA = 1
GROUP BY p.id, p.name

В моем понимании подзапросы не поддерживаются в JPA

Они есть, но не в пунктах FROM (хотя некоторые провайдеры JPA также поддерживают это).

...