2012-03-02 60 views
3

这是我简单的JPQL: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。 这里有什么错?

回答

10

这样的查询没有意义。如果您使用GROUP BY,则应汇总SELECT中的其他属性。因为它是在JPA规范表示:

为SELECT子句的要求时使用GROUP BY遵循 那些SQL的:即,在SELECT子句中出现 (除了作为聚合函数的任何项目或作为聚合 函数的参数)也必须出现在GROUP BY子句中。在组成 组时,为了分组目的,空值被视为相同。

如果您想查询的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:分组查询 的选择列表中至少包含一个无效的表达式。如果SELECT列表具有GROUP BY,则该列表可能只包含有效的分组表达式和有效的 聚合表达式。

答评论: 一个网站可能包含属性也比其他siteType也。允许使用下面的例子:

public class Site { 
    int id; 
    String siteType; 
} 

和两个实例:(ID = 1,siteType = “相同”),(ID = 2,siteType = “相同的”)。现在,当select的类型是Site本身(或者它的所有属性),并且你通过siteType进行分组时,不可能定义结果是否有id值为1或2的结果。这就是为什么你必须使用一些聚合函数AVG,它给你属性值的平均值)剩余的属性(在我们的例子中是id)。

此链接的背后:ObjectDB GROUP BY你可以找到一些GROUP BY和聚合的例子。

+0

Thx。所以它不可能做一个类型查询(TypedQuery q)然后用这个GROUP BY? – BigJ 2012-03-02 18:48:59

+0

不客气。一般情况下,可以使用带有GROUP BY的TypedQuery,但在这种情况下,由于在select中缺少聚合,所以构建查询是不可能的。 – 2012-03-02 18:54:36

+0

不知道我是否遵循。为什么我在选择中缺少聚合?我可以添加它们吗? – BigJ 2012-03-02 18:59:17