Laravel项目中MySQL严格模式下用Join替代Group By查询方案咨询
解决MySQL严格模式下用Join替代GROUP BY获取分组任意记录的问题
我完全理解你的困扰——MySQL严格模式下,那种只按fruitModel分组却直接选fruitName的非标准查询确实会被拦截,因为不符合SQL标准(SELECT列要么在GROUP BY里,要么被聚合函数包裹)。用Join来实现需求是个很棒的思路,下面给你具体的方案:
纯SQL自Join方案
核心思路是通过自关联表,筛选出每个fruitModel下的任意一条记录(这里以获取每个model对应的最小fruitName为例,你也可以根据需求调整成最大,或者用主键筛选更稳定):
SELECT a.fruitModel, a.fruitName FROM fruits a LEFT JOIN fruits b ON a.fruitModel = b.fruitModel AND a.fruitName > b.fruitName -- 换成<即可获取该model下最大的fruitName WHERE b.fruitName IS NULL;
原理说明
这个查询把fruits表和自身做左关联,条件是同一个fruitModel且a的fruitName比b的大。当a的fruitName是该model下最小的那条时,找不到任何满足条件的b记录,此时b.fruitName会是NULL,这条a记录就会被保留下来——最终每个fruitModel只会返回一条符合要求的记录。
如果你的表有主键(比如id),用主键来筛选会更可靠(避免fruitName重复的情况),SQL调整为:
SELECT a.fruitModel, a.fruitName FROM fruits a LEFT JOIN fruits b ON a.fruitModel = b.fruitModel AND a.id > b.id WHERE b.id IS NULL;
Laravel项目中的实现(Eloquent/DB门面)
直接把上面的SQL转换成Laravel的查询构建器写法,方便你在项目中使用:
用fruitName筛选的版本
$uniqueFruits = DB::table('fruits as a') ->leftJoin('fruits as b', function ($join) { $join->on('a.fruitModel', '=', 'b.fruitModel') ->where('a.fruitName', '>', 'b.fruitName'); }) ->whereNull('b.fruitName') ->select('a.fruitModel', 'a.fruitName') ->get();
用主键id筛选的版本(推荐)
$uniqueFruits = DB::table('fruits as a') ->leftJoin('fruits as b', function ($join) { $join->on('a.fruitModel', '=', 'b.fruitModel') ->where('a.id', '>', 'b.id'); }) ->whereNull('b.id') ->select('a.fruitModel', 'a.fruitName') ->get();
这样的查询完全符合MySQL严格模式的要求,而且不需要用到GROUP BY,完美解决你的问题~
内容的提问来源于stack exchange,提问作者Lolo
相关产品推荐
相关产品推荐

