Я пытаюсь написать запрос для расчета столбца ранга на основе совокупного столбца.Запрос является SQLProjection как часть запроса Hibernate Criteria. Вот что я попробовал:
String sqlProjection =
"(select count(*) from IPTStatistic stat2 where
max(s.powerRestarts) > max({alias}.powerRestarts)) as rank)";
ProjectionList list = Projections.projectionList();
list.add(Projections.sqlProjection(sqlRankQuery, new String[]{"rank"}, new Type[]{new IntegerType()})));
list.add(Property.forName("managedObjectName").group());
list.add(Projections.max("powerRestarts").as("maxRestarts"));
Criteria crit = hibernateSessionHelper.getSessionFactory().getCurrentSession().createCriteria(IPTStatistic.class);
crit.setProjection(projection);
crit.list();
Когда я использую неагрегированный столбец в проекции SQL, подвыбор работает, и я получаю ожидаемые результаты, это только один раз, когда явведите max()
, что происходит ошибка.
Это выдает довольно неопределенный org.hibernate.exception.GenericJDBCException
с сообщением "Could not execute query
".
В журнале показывается:
WARN logExceptions, SQL Error: -458, SQLState: S1000
ERROR logExceptions, java.lang.NullPointerException java.lang.NullPointerException
Я не могу точно определить проблему в запросе из приведенных выше сообщений об ошибках. Может ли кто-нибудь дать мне несколько советов о том, как исправить мой запрос?
ОБНОВЛЕНИЕ:
Я сейчас использую следующий sqlProjection в соответствии с ответом axtavt ниже:
String sqlProjection = "(select count(*) from " +
"(select name from IPTStatistic s group by s.name " +
" having max(s.powerRestarts) > max({alias}.powerRestarts)) " +
"as r) as rank"
SQL, сгенерированный Hibernate:
select (select count(*) from (select iptManagedObjectName from IPTStatistic s group by s.iptManagedObjectName having max(s.powerRestarts) > max(this_.powerRestarts)) as r) as rank, this_.iptManagedObjectName as y1_, from IPTStatistic this_
Теперь я получаю ошибку:
WARN logExceptions, SQL Error: -5581, SQLState: 42581
ERROR logExceptions, unexpected token: SELECT
Если я удаляю max({alias}.powerRestarts)
и заменяю его либо константой, либо max(s.powerRestarts)
, тогда запрос работает (но, очевидно, неправильно вычисляет ранг).
Кажется, есть проблема с использованием {alias}
в этом запросе sqlProjection
- возможно, что-то связанное с вложенными подзапросами - может кто-нибудь помочь?
Спасибо.