由于非聚合列与选择DB:raw和GROUP BY导致的Laravel语法错误

时间:2017-12-12 15:54:34

标签: php laravel group-by laravel-query-builder mysql-error-1055

我有以下4个SQL表:

工作室
整数id
字符串名称
整数last_movie_id


整数id
整数studio_id
字符串类型

actor_movie
整数movie_id
整数actor_id

演员
整数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 SELECT列表的表达式#3不在GROUP BY子句中,并且包含非聚合列[...]这与sql_mode = only_full_group_by

不兼容

我不想将sql_strict_mode设置为false以避免此错误。我想了解我的查询有什么问题。我尝试使用像“ANY_VALUE”这样的聚合函数,但没有成功。

1 个答案:

答案 0 :(得分:1)

您错误地编写了查询 - 特别是

{p> \DB::raw('(SELECT movies.type FROM movies WHERE movies.id = studios.last_movie_id') as type位于select语句中。此查询为您提供而不是COLUNM NAME,该select语句应位于select col1Name, col2Name, .... from ....语句中。{/ p>

因为你没有提供完整的桌面结构和关系(即你在查询中提到的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();