У меня есть следующие 4 таблицы SQL:
студии
целое число
имя строки
целое число last_movie_id
фильмы
целое число
целое число studio_id
тип строки
actor_movie
integer movie_id
целое число actor_id
актеры
целое число
имя строки
Я пытаюсь создать запрос, который дает мне конкретного актера, список студий, в которых он работал, включая последний фильм студии (играет ли актер в нем или нет):
Мой код следующий (в ActorController):
$actor = \App\Actor::findOrFail($id);
$studios = \DB::table('actor_movie')
->leftjoin('movies', 'actor_movie.movie_id', '=', 'movies.id')
->leftjoin('studios', 'studios.id', '=', 'movies.studio_id')
->select(
'studios.name',
'studios.last_movie_date'
\DB::raw('(SELECT movies.type FROM movies WHERE movies.id = studios.last_movie_id') as type')
->where('actor_movie.actor_id', $actor->id)
->groupBy('studios.name', 'studios.last_movie_date', 'type')
->get();
Но у меня есть следующая ошибка:
SQLSTATE [42000]: синтаксическая ошибка или нарушение прав доступа: 1055 Выражение № 3 списка SELECT отсутствует в предложении GROUP BY и содержит неагрегированный столбец […], это несовместимо с sql_mode = only_full_group_by
Я не хочу устанавливать sql_strict_mode в false, чтобы обойти эту ошибку. Я хотел бы понять, что не так с моим запросом. Я пытался использовать функции агрегирования, такие как «ANY_VALUE», но ничего не получилось.
Вы неправильно написали запрос — конкретно
\DB::raw('(SELECT movies.type FROM movies WHERE movies.id = studios.last_movie_id') as type
который в select
заявление. Этот запрос дает вам ценности) не COLUNM NAME
который должен быть в select
утверждение как select col1Name, col2Name, .... from ....
,
Поскольку вы не предоставили полные структуры таблиц & Отношение (т. е. вы упомянули studios.last_movie_date в запросе, но не в вопросе), кому-либо очень трудно дать вам правильный запрос, но приведенное ниже должно работать нормально —
$actor = \App\Actor::findOrFail($id);
$studios = \DB::table('actor_movie')
->leftjoin('movies', 'actor_movie.movie_id', '=', 'movies.id')
->leftjoin('studios', 'studios.id', '=', 'movies.studio_id')
->leftjoin('movies as mov2', 'studios.last_movie_id', '=', 'mov2.id')
->select(
'studios.name',
'studios.last_movie_date',
'mov2.type'
)
->where('actor_movie.actor_id', $actor->id)
->groupBy('studios.name', 'studios.last_movie_date', 'type')
->get();
Что касается других вопросов, я думаю, у вас есть идея.
Как бы я это сделал —
создать миграцию для запроса ниже —
create view actors_studio as
select am.actor_id, mov.studio_id, std.name as studio_name, std.last_mov_id, mov2.type as last_mov_type
from actor_movie as am
left join movies as mov on am.movie_id = mov.id
left join studios as std on std.id = mov.studio_id
left join movies as mov2 on std.last_movie_id = mov2.id
group by actor_id, studio_id, studio_name, last_mov_id, last_mov_type
order by actor_id, studio_id;
Затем запустите команду migrate и создайте модель для просмотра. actors_studio
т.е. VwActorStudios
а затем простой запрос
$studios = VwActorStudios::where('actor_id', $actor->id)->get();
Других решений пока нет …