SQL-запрос выдает исключение не в агрегатной функции или группе по предложению

Я работаю над исправлением набора тестов для нашего проекта, который тестируется через Hibernate/DBUnit. Есть несколько тестовых случаев, которые выдают похожее исключение из Hibernate, которое выглядит примерно так:

java.sql.SQLException: не в агрегированной функции или группе по предложению: org.hsqldb.Expression@109062e в операторе [... бла ...]

Погуглив, я подозреваю, что это вызвано использованием нами агрегатной функции AVG(), поскольку она содержится в сообщении об исключении, и все выбрасываемые запросы содержат ее. Однако я обнаружил несколько ссылок на людей, которые получали эту ошибку, и смог исправить ее, либо закомментировав предложение «ORDER BY» или «GROUP BY», либо включив в группировку другие столбцы из предложения SELECT. Я понимаю, почему это исправит такое сообщение об ошибке, но я не уверен, применимо ли это к моей ситуации, потому что я пытался сделать то же самое, и это не имело никакого значения. Кроме того, у нас есть несколько тестовых случаев, вызывающих исключения, которые используют ORDER/GROUP, но не все. Например:

ThingerVO myThinger = (ThingerVO)session.createQuery("SELECT new ThingerVO(" +
"r.id, " + "u.id, " + "u.alias, " + "s.id, " +
"s.name, " + "r.URL," + "AVG(v.rating), " +
"r.totalCount, " + "r.isPrivate, " + "a.id, " +
"a.name, " + "r.transactionId, " + "r.size, " +
"u.hasPicture " +
") FROM Thinger r LEFT OUTER JOIN r.votes as v, Table1S s " +
"JOIN s.Table2A AS a, User u " +
"WHERE r.userId = u.id AND " +
"s.id = r.Table1SId AND " +
"r.id = :thingId")    
.setInteger("thingId", thingId)
.uniqueResult();

Этот запрос также вызывает то же самое исключение, даже если он не использует предложение ORDER/GROUP. Кроме того, я вырезал/вставил сгенерированный код HSQL из Hibernate прямо в браузер запросов MySQL, и он заработал без проблем. Кроме того, стоит отметить, что весь этот код отлично работает в нашей производственной базе данных, поэтому я действительно не понимаю, почему он выбрасывает сюда.

Некоторая другая потенциально полезная информация — мы используем плоскую структуру базы данных XML с некоторыми фиктивными тестовыми данными для тестовых случаев и диалектом MySQL для гибернации. Мы используем dbunit 2.4.3/спящий режим 3.2.6. Я пытался использовать последнюю версию спящего режима 3.3.1, но она вел себя так же.

Любые указатели или подсказки будут очень признательны.


person Nik Reiman    schedule 24.02.2009    source источник


Ответы (3)


Если вы используете агрегатную функцию (например, AVG()) в части SELECT SQL-запроса вместе с другими неагрегатными выражениями, то у вас должно быть предложение GROUP BY, в котором должны быть перечислены все неагрегатные выражения.

Я не знаком с java, но, глядя на код, похоже, что он собирается создать и выполнить запрос примерно так (не совсем правильно, но достаточно близко, я думаю):

SELECT r.id, 
       u.id,
       u.alias,
       s.id, 
       s.name, 
       r.URL, 
       AVG(v.rating), 
       r.totalCount, 
       r.isPrivate, 
       a.id, 
       a.name, 
       r.transactionId,
       r.size, 
       u.hasPicture 
FROM Thinger r 
LEFT OUTER JOIN r.votes as v, 
                     Table1S s 
JOIN s.Table2A AS a, User u 
WHERE r.userId = u.id 
AND s.id = r.Table1SId 
AND r.id = :thingId

... Это не имеет GROUP BY, но смешивает агрегатные и неагрегатные выражения в предложении SELECT. Проблема в том, что SQL плохо сформирован.

Исправление состоит в том, чтобы добавить GROUP BY в конец запроса.

Я не могу сказать, почему это работает в вашей производственной системе, но я подозреваю, что там есть некоторая тонкая разница. Возможно, что-то добавляет GROUP BY автоматически?

Можете ли вы опубликовать распечатку SQL, который он выполняет?

person AJ.    schedule 24.02.2009
comment
Хорошо, я мог бы ПОКЛЯТЬСЯ, что добавил все столбцы в моем предложении SELECT в GROUP BY, но я думаю, что это то, что я получаю для отладки в предрассветные часы ночи. В любом случае, добавление всех этих столбцов (за исключением, очевидно, столбца AVG) теперь устраняет проблему. Спасибо! - person Nik Reiman; 24.02.2009
comment
Не беспокойся. Я замечаю это только потому, что постоянно делаю такие ошибки. ;) - person AJ.; 24.02.2009
comment
SQL. Сервер. Отстой. - person Amalgovinus; 06.07.2016

Кроме того, ORDER BY не работает в hsqldb, если поле сортировки не является строкой.

К сожалению, это приводит к сообщению об ошибке Не в агрегатной функции или группировке по предложению, что предполагает проблему группировки, отсюда и путаница...

См.: http://markmail.org/message/42vmifme4opz4jgl.

person Aleksander Adamowski    schedule 22.01.2010

В некоторых системах (например TALEND) запрос не работает, если есть строки комментария пример:

SELECT r.id,   
   u.alias,
   AVG(v.rating), 
   r.totalCount
FROM Thinger r 
LEFT OUTER JOIN r.votes as v, 
                     Table1S s 
JOIN s.Table2A AS a, User u 
WHERE r.userId = u.id 
AND s.id = r.Table1SId 
AND r.id = :thingId
--AND r.name is not null 
GROUP BY r.id, u.alias, r.totalCount

Выдает ошибку для запросов MS SQL. Вместо строки комментария

--

используйте эти символы для комментариев

/* И r.name не равно null */

Может кому поможет и сэкономит время.

person Andrius V.    schedule 27.03.2014