JPQL Group不工作

时间:2012-03-02 16:14:44

标签: group-by 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。 这有什么不对吗?

1 个答案:

答案 0 :(得分:10)

这样的查询没有意义。如果使用GROUP BY,则应聚合SELECT中的其他属性。正如JPA规范中所述:

  

使用GROUP BY时对SELECT子句的要求如下   SQL的那些:即SELECT子句中出现的任何项   (作为聚合函数或作为聚合的参数除外)   function)也必须出现在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列表   包含至少一个无效表达式。如果SELECT列表具有GROUP   BY,列表可能只包含有效的分组表达式并且有效   聚合表达式。

回答评论: 一个站点也可能包含除siteType之外的其他属性。让我们使用以下示例:

public class Site {
    int id; 
    String siteType;
} 

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

在此链接后面:ObjectDB GROUP BY您可以找到GROUP BY和聚合的一些示例。