Мне нужен запрос для преобразования времени (миллисек) в почасовое распределение.
в моей таблице есть столбец с именем timestamp: значение в миллисекундах. чтобы сгруппировать по часам, мне нужно сделать следующее: разделить на 1000 -> разделить на 3600 секунд -> часы -> мод 24 -> получить час дня, когда были созданы записи.
временная метка длинная:
public static volatile SingularAttribute<VersionJpa, Long> timestamp;
Затем я могу отобразить результаты в дневном распределении. Однако это не работает, группа не работает, и я получаю полный список, не сгруппированный и не подсчитанный.
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Tuple> cq = cb.createTupleQuery();
Root<VersionJpa> root = cq.from(VersionJpa.class);
cq.where(p);
Expression<Integer> group = cb.mod(cb.toInteger(cb.quot(root.get(VersionJpa_.timestamp), 3600000)),24);
cq.multiselect(group, cb.count(root));
cq.groupBy(group);
TypedQuery<Tuple> tq = em.createQuery(cq);
return tq.getResultList();
этот SQL (mysql) дает правильные результаты. есть ли эквивалентный пол в JPA? Пробовал как.(Целое число) || toInteger()
select mod(floor(stamp/3600000), 24) , count(*) from versions group by mod(floor(stamp/3600000), 24);
Я обнаружил, что во время модульного теста (на Derby) это работает хорошо, но в более продуктивной среде, такой как установка (MySQL), он не преобразует самый внутренний агрегат в целое число, поэтому группа выполняется с плавающими значениями, а не с 24 (0). , 1, .. 23) потенциальные значения (возврат тысяч групп).
Expression<Integer> hours = cb.mod(cb.quot(root.get(VersionJpa_.timestamp).as(Integer.class), 3600000).as(Integer.class),24).as(Integer.class);
cq.multiselect(hours, cb.count(root));
cq.groupBy(hours);
добавление поддержки и тестирования PostgreSQL приводит к еще одной ошибке, которая заставляет меня думать, что мой запрос неверен:
RuntimeException Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.0.v20130507-3faac2b): org.eclipse.persistence.exceptions.DatabaseException Internal Exception: org.postgresql.util.PSQLException: ERROR: column "versions.stamp" must appear in the GROUP BY clause or be used in an aggregate function Position: 13 Error Code: 0 Call: SELECT MOD((STAMP / ?), ?), COUNT(ID) FROM VERSIONS GROUP BY MOD((STAMP / ?), ?) LIMIT ? OFFSET ? bind => [6 parameters bound] Query: TupleQuery(referenceClass=VersionJpa sql="SELECT MOD((STAMP / ?), ?), COUNT(ID) FROM VERSIONS GROUP BY MOD((STAMP / ?), ?) LIMIT ? OFFSET ?")
любая помощь приветствуется.