У меня есть таблица с полем отметки времени типа datetime. Мне нужно агрегировать данные между определенным временем начала и окончания в группы x, представляющие интервалы времени равной длины, где x предоставляется как параметр функции.
Как лучше всего сделать это с помощью Hibernate?
Обновлено: некоторые объяснения
Таблица mysql:
data_ts: datetime pk
value1 : int
value2 : bigint
...
Класс сущности:
Calendar dataTs;
Integer value1;
BigDecimal value2;
...
Я ищу HQL-запрос, который делает что-то вроде
select max(c.value1), avg(c.value2) from MyClass c
where c.dataTs between :start and :end group by <interval>
где весь период времени сгруппирован в x временных интервалов одинакового размера.
Пример:
Start : 2008-10-01 00:00:00
End : 2008-10-03 00:00:00 (2 days)
Groups: 32
необходимо сгруппировать по временному интервалу 1,5 часа (48 часов / 32):
2008-10-01 00:00:00 - 2008-10-01 01:29:59
2008-10-01 01:30:00 - 2008-10-01 02:59:59
2008-10-01 02:00:00 - 2008-10-01 04:29:59
...




Hibernate предназначен для отображения между графом объектов (сущностей и типов значений) и их представлением в реляционной базе данных.
Из описания вашего вопроса вы на самом деле не упоминаете какие-либо объекты, которые вы моделируете, поэтому я бы предложил перейти к собственному SQL-запросу.
http://www.hibernate.org/hib_docs/reference/en/html/querysql.html
Возможно, если вы разместили структуру таблицы, это может дать больше контекста для вашего вопроса?
Я пытался решить ту же проблему. Мне нужно сгруппировать данные по 2-часовому интервалу в течение одного дня. Фактически, «чистый» Hibernate не должен использоваться таким образом. Поэтому я добавил проекцию собственного SQL в критерии Hibernate. В вашем случае это может выглядеть так (я использую синтаксис и функции MySQL):
int hours = 2; // 2-hours interval
Criteria criteria = session.createCriteria( MyClass.class )
.add( Restrictions.ge( "dataTs", start ) )
.add( Restrictions.le( "dataTs", end ) );
ProjectionList projList = Projections.projectionList();
projList.add( Projections.max( "value1" ) );
projList.add( Projections.avg( "value2" ) );
projList.add( Projections.sqlGroupProjection(
String.format( "DATE_ADD( DATE( %s_.dataTs ), INTERVAL( HOUR( %s_.dataTs ) - HOUR( %s_.dataTs) %% %d ) HOUR) as hourly", criteria.getAlias(), criteria.getAlias(), criteria.getAlias(), hours ),
String.format( "DATE_ADD( DATE( %s_.dataTs ), INTERVAL( HOUR( %s_.dataTs) - HOUR( %s_.dataTs ) %% %d ) HOUR)", criteria.getAlias(), criteria.getAlias(), criteria.getAlias(), hours ),
new String[]{ "hourly" },
new Type[]{ Hibernate.TIMESTAMP } )
);
criteria.setProjection( projList );
List results = criteria
.setCacheable( false )
.list();
Код выглядит немного некрасиво, но он решает проблему. Надеюсь, общая идея будет вам полезна.