JPQL Group By не работает - PullRequest
       31

JPQL Group By не работает

3 голосов
/ 02 марта 2012

Это мой простой JPQL:

SELECT s
FROM Site s
GROUP BY s.siteType

siteResult = q.getResultList();
for (Site site : siteResult) {
    // loops all sites
}

Этот запрос возвращает все сайты, включая сайты с одинаковым типом сайта. Я использую JPA 2.0 Eclipselink. Что здесь не так?

1 Ответ

10 голосов
/ 02 марта 2012

Такой запрос не имеет смысла.Если вы используете 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 должны быть выбраны.

В таком случае EclipseLink с derby просто удаляет 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").Теперь, когда типом выбора является сам сайт (или все его атрибуты), и вы создаете группу по siteType, невозможно определить, должен ли результат иметь один со значением идентификатора 1 или 2. Вот почему вы должны использовать некоторую статистическую функцию (например,AVG, который дает вам среднее значение значений атрибутов) для оставшихся атрибутов (в нашем случае это id).

За этой ссылкой: ObjectDB GROUP BY вы можете найти несколько примеров с GROUP BY и агрегатами.

...