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

Posted

技术标签:

【中文标题】由于选择 DB:raw 和 GROUP BY 的非聚合列导致 Laravel 语法错误【英文标题】:Laravel syntax error due to nonaggregated column with select DB:raw and GROUP BY 【发布时间】:2018-05-26 09:00:06 【问题描述】:

我有以下 4 个 SQL 表:

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

电影 整数ID 整数 studio_id 字符串类型

actor_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”之类的聚合函数,但没有任何结果。

【问题讨论】:

Error related to only_full_group_by when executing a query in mysql的可能重复 movies.type 如果不需要在选择中使用嵌套选择,难道movies.type 不会工作吗(这真的很难看)? 【参考方案1】:

你写错了查询 - 特别是

\DB::raw('(SELECT movies.type FROM movies WHERE movies.id = studios.last_movie_id') as typeselect 语句中。此查询为您提供而不是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();

【讨论】:

非常感谢。添加与电影表的第二个连接是正确的做法!完美,谢谢!

以上是关于由于选择 DB:raw 和 GROUP BY 的非聚合列导致 Laravel 语法错误的主要内容,如果未能解决你的问题,请参考以下文章

在 SQL 中选择不在 Group By 中的列

如何在 Teradata SQL 中使用 LEFT JOIN 对查询中的非聚合参数进行 GROUP BY?

解决Mysql5.7以上版本, 使用group by抛出Expression #1 of SELECT list is not in GROUP BY clause and contains no异常

在非聚合中使用聚合结果导致 GROUP BY 出现问题

在 mysql 中使用 group by 查询和 order by 查询选择

当查询有 GROUP BY 时如何获得总数的百分比?