Несколько агрегатных функций в Hibernate Query

Я хочу иметь запрос HQL, который по существу делает это:

select quarter, sum(if(a>1, 1, 0)) as res1, sum(if(b>1, 1, 0)) as res2 from foo group by quarter;

Я хочу список в качестве выходного списка с Summary Class ->

Class Summary
{
long res1;
long res2;
int quarter;
}

Как я могу добиться этой агрегации в HQL? Какими будут сопоставления гибернации для целевого объекта? Я не хочу использовать SQL-запрос, который возвращает List<Object[]>, а затем преобразует его в List<Summary>.


person TJ-    schedule 18.04.2012    source источник


Ответы (2)


Поскольку Summary не является сущностью, вам не нужно для него сопоставление, вы можете создать соответствующий конструктор и вместо этого использовать выражение конструктора HQL. Агрегатные функции и if также возможны, хотя вам нужно использовать синтаксис case вместо if.

Итак, если Foo является сущностью, сопоставленной с таблицей Foo, это будет выглядеть так:

select new Summary(
    f.quarter,
    sum(case when f.a > 1 then 1 else 0 end),
    sum(case when f.b > 1 then 1 else 0 end)
) from Foo f group by f.quarter

См. также:

person axtavt    schedule 18.04.2012

Это может быть возможно с подзапросом в отображении. Взгляните на Более сложные сопоставления ассоциаций в документации по hibernate. Я никогда не пробовал такую ​​возможность.

Но даже специалисты по спящему режиму рекомендуют «… но практичнее обрабатывать такие случаи с помощью HQL или критериального запроса.». Вот что я бы сделал: использовал group-by в HQL. выписка и работа со списком. Дополнительное время на копирование этого списка в список подходящих объектов ничтожно мало по сравнению со временем, которое группировка использует в базе данных. Но, похоже, вам не нравится такая возможность.

Третья возможность — определить представление в базе данных, содержащее вашу группу, а затем создать нормальное отображение для этого представления.

person Johanna    schedule 18.04.2012