2012-03-02 67 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