MySQL и MariaDB LinuxWindowsmacOS 105542000

Как исправить ONLY_FULL_GROUP_BY без отключения проверки MySQL

  • Обновлено
  • Чтение ≈ 4 минуты

Краткий ответ

Ошибка ERROR 1055 (42000) после обновления MySQL возникает, когда SELECT выводит неагрегированный столбец, который не входит в GROUP BY и не зависит функционально от группировки. Режим ONLY_FULL_GROUP_BY предотвращает неопределённый выбор значения из группы. Правильное решение — уточнить смысл результата и запрос, а не выключить проверку на всём сервере.

В этой статье
  1. Что означает неисправность
  2. Возможные причины и признаки
  3. Пошаговая диагностика и решение
  4. Команды для диагностики и проверки
  5. Пример для отдельной тестовой базы или учебного проекта
  6. Проверка результата и дальнейшие действия

#Что означает неисправность

Ошибка ERROR 1055 (42000) после обновления MySQL возникает, когда SELECT выводит неагрегированный столбец, который не входит в GROUP BY и не зависит функционально от группировки. Режим ONLY_FULL_GROUP_BY предотвращает неопределённый выбор значения из группы. Правильное решение — уточнить смысл результата и запрос, а не выключить проверку на всём сервере.

#Возможные причины и признаки

Возможная причинаКак узнатьЧто делать
Выбрано поле без правила агрегацииSELECT customer_id, product, SUM(amount) группирует только по customer_id, хотя товаров в группе несколько.В ошибке названо поле product, которого нет в GROUP BY.Убрать поле, агрегировать его или определить отдельное правило выбора.
Запрос выбирает случайную строку группыРазработчик рассчитывал получить последнее значение без явного порядка.После обновления отказ при прежнем запросе, результат старой версии был непредсказуем.Использовать оконную функцию/подзапрос с явным порядком и разрешением ничьих.
Неполная функциональная зависимостьВ GROUP BY не включён ключ или объединение не гарантирует один результат на группу.Ошибка появляется после добавления JOIN либо при иной схеме уникальности.Проверить уникальные ключи и семантику объединения.

#Пошаговая диагностика и решение

  1. Сохраните точный запрос и названный в ошибке столбецОткройте журнал веб-приложения или SQL-редактор, скопируйте текст запроса и ERROR 1055. Не запускайте запрос, если это DELETE/UPDATE с вложенными операциями: для диагностики нужна безопасная выборка на тестовой базе. Отметьте, что именно должна показывать страница — сумму по клиенту, последний заказ или перечень товаров, — иначе нельзя выбрать корректную агрегацию.
  2. Проверьте sql_mode в том же соединенииВ MySQL Workbench откройте подключение → SQL Editor или запустите mysql и выполните SELECT @@SESSION.sql_mode;. Найдите ONLY_FULL_GROUP_BY среди перечисленных режимов; @@GLOBAL относится к настройке будущих соединений и может отличаться. Если строка не содержит режим, но приложение падает, проверьте её фактическое соединение и версию MySQL.
  3. Разберите SELECT, GROUP BY и зависимость по ключамВ проблемном SQL подчеркните все выражения после SELECT. Для каждого проверьте: это агрегат SUM/MAX/COUNT, поле в GROUP BY или значение однозначно определяется сгруппированным уникальным ключом? Если ни одно условие не выполняется, запрос неоднозначен. Не добавляйте все поля в GROUP BY автоматически: это может раздробить суммы на другое число строк.
  4. Для итогов по группам уберите несущественное полеЕсли нужен оборот по клиенту, тестовый SQL должен выбирать customer_id и SUM(amount), группируя только по customer_id. Название товара не имеет единственного значения на весь итог клиента. Исправьте SELECT в исходном репозитории проекта, а не временно в SQL-редакторе, затем сравните итоги с контрольными данными.
  5. Если нужен последний заказ, выберите строку определённым правиломВ MySQL 8.0/8.4 можно использовать ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY created_at DESC, id DESC) в подзапросе, затем оставить rn = 1. Включение уникального id в порядок устраняет неоднозначность записей с одинаковым временем. Если задача требует другой логики (первый заказ, максимум суммы), уточните правило у владельца отчёта.
  6. Используйте ANY_VALUE только при согласованной произвольностиФункция ANY_VALUE(product) позволяет вернуть произвольное значение группы, когда выбор любого варианта действительно допустим бизнес-логикой. Это не эквивалент «последний» или «самый популярный» и не исправление качества данных. На тестовой выборке сравните возвращаемую колонку с ожидаемым правилом: если нужна определённая запись, используйте отдельный подзапрос.
  7. Не выключайте ONLY_FULL_GROUP_BY глобальноКоманда SET GLOBAL sql_mode=... влияет на новые подключения и может скрыть логические ошибки сразу нескольких приложений. Разовое удаление ONLY_FULL_GROUP_BY из сессионного режима допустимо лишь как временный диагностический эксперимент в изолированной тестовой базе, но не как опубликованное исправление. После теста закройте соединение и вернитесь к нормальным настройкам.
  8. Протестируйте одинаковую выборку до и после измененийПодготовьте два клиента, у каждого несколько заказов с разными товарами и временем. Запустите исправленный запрос в тестовой базе, проверьте итог суммы и последнюю запись отдельно. Ожидается выполнение без 1055 при включённом ONLY_FULL_GROUP_BY и совпадение расчёта с ручной проверкой; при неуспехе сравните JOIN и уникальные ключи.

#Команды для диагностики и проверки

SQLКоманда
Только чтение; выполните в SQL Editor MySQL Workbench или консоли mysql. Значения SESSION и GLOBAL могут различаться.
SELECT VERSION(), @@SESSION.sql_mode AS session_sql_mode;
SELECT @@GLOBAL.sql_mode AS global_sql_mode;

#Пример для отдельной тестовой базы или учебного проекта

SQL
Только тестовое соединение MySQL 8.0 или 8.4. Первая выборка возвращает total=300, вторая — Карта как последний заказ; временная таблица исчезнет при закрытии соединения.
CREATE TEMPORARY TABLE whelp_orders (id INT PRIMARY KEY, customer_id INT, product VARCHAR(30), amount INT, created_at DATETIME);
INSERT INTO whelp_orders VALUES (1,1,'Книга',100,'2026-01-01'),(2,1,'Карта',200,'2026-01-02');
SELECT customer_id, SUM(amount) AS total FROM whelp_orders GROUP BY customer_id;
SELECT customer_id, product FROM (SELECT customer_id, product, ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY created_at DESC,id DESC) AS rn FROM whelp_orders) AS ranked WHERE rn=1;

#Проверка результата и дальнейшие действия

После изменения отчёта запрос выполняется без ERROR 1055 при неизменном @@SESSION.sql_mode; суммы и выбранные записи проверены вручную на контрольном наборе. Если запрос стал работать, но цифры изменились, не считайте это успехом: восстановите прежнюю версию кода в тестовой среде и заново согласуйте значение каждой выводимой колонки.

Источники и обновления

Последнее обновление статьи: 2 ноября 2026. Версии программ и интерфейсы меняются — если шаги не совпадают с вашей версией, сверяйтесь с документацией производителя.