我正在尝试编写一个查询来根据聚合列计算排名列。该查询是作为 Hibernate Criteria 查询一部分的 SQLProjection。这是我尝试过的:
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
我无法从上述错误消息中自己查明查询中的问题,谁能给我一些关于如何更正我的查询的指示?
更新:
我现在根据下面的 axtavt 的回答使用以下 sqlProjection:
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"
Hibernate生成的SQL是:
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
- 可能与嵌套子查询有关 - 任何人都可以帮忙吗?
谢谢你。