hibernate中的hql不支持sum(distinct)语句

在进行数据统计时,经常会使用聚合函数,在hibernate中也支持聚合函数。如进行以下的统计查询:

select sum(distinct 奖牌) from 成绩 inner join 参赛运动员 inner join 运动员的学校 group by 学校

在上面的数据模型中,成绩与参赛运动员为一对多关系,即可能为多个运动员以团体参赛的形式参加一个项目,最终取得一条成绩。运动员与学校为多对一关系。在上面的查询中,为避免在同一个成绩中,由团体参赛的运动员来自同一个学校,因为只能记为一个奖牌,而不是N(N为参赛运动员数量)。因此,需要使用distinct对重复的成绩进行过滤,并按学校分组。

在正常的sql查询下,现在的数据库已经支持在sum聚合函数中进行distinct操作了。而在hibernate中,使用如此的查询会报一个如下的错误:

org.hibernate.hql.ast.QuerySyntaxException: unexpected token: distinct

即不支持在sum函数中带有distinct语句,在相关的bug列表中。网页:https://hibernate.onjira.com/browse/HHH-6311 也描述了这一问题,且值到现在还没有解决。那么为什么会产生这个错误呢,这是由hibernate将hql转换为sql的过程中产生的,即在hibernate的语法树中,就不支持这样的写法。相关的语法描述中,针对聚合函数是这样的(在源文件hql.g中)

:aggregate
	: ( SUM^ | AVG^ | MAX^ | MIN^ ) OPEN! additiveExpression CLOSE! { #aggregate.setType(AGGREGATE); }
	// Special case for count - It's 'parameters' can be keywords.
	|  COUNT^ OPEN! ( STAR { #STAR.setType(ROW_STAR); } | ( ( DISTINCT | ALL )? ( path | collectionExpr ) ) ) CLOSE!
	|  collectionExpr
	;

在上面的描述中,只有count支持带distinct或all描述语句,而其它的如sum,avg,max,min均不支持,因此在进行转换时即会产生异常。因为,只能采用sql的方法实现上面的统计查询了。好在使用session.createSQLQuery,只需要将hql进行简单的人工转换再加上addScalar进行结果类型转换即能实现操作,实现上难度不大。

参考文章:Antlr–看Hibernate3如何解释HQL语言

转载请标明出处:i flym
本文地址:https://www.iflym.com/index.php/code/201207190001.html

相关文章:

作者: flym

I am flym,the master of the site:)

发表评论

邮箱地址不会被公开。 必填项已用*标注