Shlop
@Shlop
Full Stack Developer (PHP/Laravel/JavaScript)

Как правильно добавить groupBy в запрос?

Здравствуйте, подскажите пожалуйста, на сайте есть категории, а у категорий есть характеристики, у некоторых категорий бывает что какая то часть характеристик схожа, и мне нужно убрать эти дубликаты, то есть оставить у категорий только уникальные характеристики, и хотелось бы это сделать запросом к БД а не в контроллере с помощью php.
В итоге я делаю такой вот запрос к БД:
$categories = Category::whereIn('id',$request->input('categories'))->with(['characteristics' => function($query) {
            $query->groupBy('id');
        }])->get();

laravel генерируют такой вот запрос:
select `characteristics`.*, `category_characteristic`.`category_id` as `pivot_category_id`, `category_characteristic`.`characteristic_id` as `pivot_characteristic_id` from `characteristics` inner join `category_characteristic` on `characteristics`.`id` = `category_characteristic`.`characteristic_id` where `category_characteristic`.`category_id` in (51, 52) group by `id`

И в итоге получаю следующую ошибку:
Ошибка в запросe (1055): Expression #5 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'rqt1mvsaw_js3ht.category_characteristic.category_id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

Но если убираю $query->groupBy('id'); то запрос выполняется корректно и в итоге получаю следующий результат, на скриншоте красным выделил дубликат характеристики в двух категориях
5dd423c933028801645800.png
Подскажите пожалуйста, как можно решить данную проблему ? Заранее благодарю за ответ.
  • Вопрос задан
  • 207 просмотров
Решения вопроса 1
alexfilus
@alexfilus
Senior backend developer
Это правильное поведение базы для такого запроса. Чтобы избежать двусмысленности, в случае если используется группировка, то либо можно в селекте использовать только поля из группировки, либо использовать агрегатные функции, либо колдовать с подзапросами. Чтобы основной запрос был валидным, с учётом агрегации, а его результаты использовать для получения остальных данных с помощью JOIN или WHERE IN
В вашем случае, если вы хотите всё же использовать Eloquent, нужно определить минимально необходимый набор данных и запросить только их. Что нужно список id и названий?
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@vism
Всегда отключаю only_full_group_by :)

Щас хэйтеры налетят, но прописывать десятки полей это жесть, и потом поддерживать если структура таблиц меняется
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы