这是我的简单JPQL:
SELECT s
FROM Site s
GROUP BY s.siteType
siteResult = q.getResultList();
for (Site site : siteResult) {
// loops all sites
}此查询返回所有站点,包括具有相同siteType的站点。我使用的是JPA 2.0 Eclipselink。这是怎么回事?
发布于 2012-03-03 00:54:08
这样的查询没有意义。如果使用GROUP BY,则应聚合SELECT中的其他属性。正如JPA规范中所说的:
当使用GROUP BY时,对SELECT子句的要求遵循
的要求:即,出现在SELECT子句中的任何项(作为聚合函数或聚合函数的参数除外)也必须出现在GROUP BY子句中。在形成组时,出于分组的目的,null值被视为相同的值。
如果您认为SQL与您的查询是对应的:
SELECT s.attr1, attr2, s.siteType
FROM site s
GROUP BY (s.siteType)您会注意到,很难想象应该选择attr1和attr2的哪个可能值。
在这种情况下,带有derby的EclipseLink只是将GROUP BY从查询中删除,这当然是处理无效JPQL的一种有点可疑的方式。我更喜欢Hibernate+MySQL对这样一个无效的JPQL的表现,它失败了,错误消息非常清楚:
java.sql.SQLSyntaxErrorException:分组查询的选择列表至少包含一个无效表达式。如果选择列表具有GROUP BY,则该列表只能包含有效的分组表达式和有效的聚合表达式。
回复评论: One网站可能还包含siteType以外的其他属性。让我们使用以下示例:
public class Site {
int id;
String siteType;
} 和两个实例:(id=1,siteType=“相同”),(id=2,siteType=“相同”)。现在,当select的类型是站点本身(或它的所有属性),并且你通过siteType进行分组时,不可能定义结果是否应该有一个id值为1或2的结果。这就是为什么你必须使用一些聚合函数(比如AVG,它给你提供属性值的平均值)来处理剩余的属性(在我们的例子中是id)。
在这个链接后面:ObjectDB GROUP BY,你可以找到一些使用GROUP BY和aggregates的例子。
https://stackoverflow.com/questions/9536602
复制相似问题