Laravel分组查询报SQL 1055 only_full_group_by不兼容如何解决?
问题原因
- MySQL开启了
only_full_group_bySQL模式(MySQL 5.7及之后版本的默认配置),要求SELECT语句中出现的非聚合字段,必须全部包含在GROUP BY子句中。你的代码里GROUP BY的字段只有search_tags.product_id,但SELECT里包含了search_tags.name字段,一个商品可能关联多个标签,MySQL无法确定该返回哪个标签名,因此抛出语法错误。 - 存在隐藏的WHERE条件逻辑优先级错误:AND的优先级高于OR,你当前拼接的条件实际执行逻辑为
满足标签匹配pen,或者(满足标签匹配drive 且 商品在售),不符合「匹配任意关键词的在售商品」的需求。 - 原写法直接把用户输入的搜索词拼接进SQL语句,存在SQL注入漏洞。
修复方案
调整查询逻辑,去掉不需要的标签字段查询,修正条件优先级,改用参数绑定防注入,调整GROUP BY逻辑即可:
$searchValues = explode(' ', $this->search); $results[0] = DB::table('search_tags') ->select('product.*') // 仅查询商品字段,不需要返回标签名就去掉search_tags.name ->join('product', 'search_tags.product_id','product.id') ->where(function ($query) use ($searchValues) { foreach ($searchValues as $word) { $query->orWhere('search_tags.name', 'LIKE', "%{$word}%"); } }) // 用闭包包住所有OR条件,保证和后面的在售判断条件优先级正确 ->where('product_quantity', '>', 0) ->where('active_status', 1) ->groupBy('product.id') // 按商品主键分组,完全符合only_full_group_by要求 ->paginate(10);
如果需要同时返回商品关联的所有匹配标签,可以在select中添加聚合函数获取:
->selectRaw('product.*, GROUP_CONCAT(search_tags.name SEPARATOR ",") as matched_tags')
内容的提问来源于stack exchange,提问作者Chinthaka
相关产品推荐
相关产品推荐

