Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Що таке режим ONLY_FULL_GROUP_BY і чому запит з GROUP BY раптом падає?

У запиті з GROUP BY кожна колонка в SELECT має бути або в GROUP BY, або всередині агрегатної функції (COUNT, SUM, MAX...). Інакше незрозуміло, яке значення показати для групи з кількох рядків.

SELECT user_id, status, COUNT(*)
FROM orders
GROUP BY user_id;
-- ERROR 1055: Expression #2 of SELECT list is not in GROUP BY clause
-- and contains nonaggregated column 'orders.status'...

У користувача кілька замовлень з різними статусами - який із них показати?

Режим ONLY_FULL_GROUP_BY (увімкнений за замовчуванням з MySQL 5.7) забороняє такі запити. Старі версії MySQL виконували їх, повертаючи значення з довільного рядка групи - і код роками працював з випадковими даними. Після оновлення MySQL такі запити раптом починають падати.

Як виправити - вирішити, що насправді потрібно:

-- групувати й за статусом
SELECT user_id, status, COUNT(*) FROM orders GROUP BY user_id, status;

-- агрегат: останній статус за датою - вже інша задача (віконна функція)
SELECT user_id, MAX(created_at) AS last_order_at FROM orders GROUP BY user_id;

-- значення справді однакове для групи (валюта клієнта), а MySQL цього не знає
SELECT user_id, ANY_VALUE(currency), COUNT(*) FROM orders GROUP BY user_id;

Функціональна залежність: MySQL дозволяє колонки, однозначно визначені колонками GROUP BY. Якщо групують за первинним ключем users.id, можна вибирати users.name - вона залежить від ключа.

Чого не робити: вимикати режим ('strict' => false у config/database.php Laravel чи прибирати його з sql_mode), щоб «запрацювало». Так помилка ховається, а результат лишається недетермінованим. PostgreSQL такі запити не дозволяє взагалі.

Докладніше в документації: Обробка GROUP BY у MySQL

1

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання