Laravel Eloquent分组报错:id需在GROUP BY或聚合函数中,求显示任意id
解决Laravel Eloquent分组时"column 'id' must appear in the GROUP BY"报错
嘿,这个PostgreSQL的分组报错我太熟了!你遇到的问题根源在于PostgreSQL严格遵循SQL标准——当你使用GROUP BY聚合数据时,SELECT子句里的所有非聚合列必须出现在GROUP BY的列表中。你的代码里选了id字段,但它没在GROUP BY里,所以数据库直接抛出了这个错误。
刚好你的需求是分组后显示每组内任意一条数据的id(首条或末条都行),这里有两种简单且靠谱的解决办法:
方法一:用聚合函数快速获取组内首/末id
如果只是需要每组里最小的id(组内最早创建的那条数据)或者最大的id(组内最后一条数据),直接用MIN()或MAX()聚合函数包裹id就搞定了,这样完全符合SQL规范:
// 导入DB门面(顶部要加这句) use Illuminate\Support\Facades\DB; // 获取每组的最小id(对应组内最早创建的那条数据) $data = Book::select(DB::raw('MIN(id) as id'), 'title', 'writer') ->groupBy('title', 'writer') ->paginate(10); // 或者获取每组的最大id(对应组内最新创建的那条数据) $data = Book::select(DB::raw('MAX(id) as id'), 'title', 'writer') ->groupBy('title', 'writer') ->paginate(10);
对了,顺便提一句:你代码里的tittle应该是拼写错误,正确的是title,我已经帮你改过来啦~
方法二:用窗口函数灵活选择组内指定数据
如果需要更灵活地挑选组内的某条数据(比如按创建时间排序后的第一条),窗口函数ROW_NUMBER()会更适合你:
use Illuminate\Support\Facades\DB; $data = Book::select( 'id', 'title', 'writer', DB::raw('ROW_NUMBER() OVER (PARTITION BY title, writer ORDER BY id DESC) as rn') ) ->having('rn', '=', 1) ->paginate(10);
这个逻辑是:先按title和writer分组,每组内按id倒序排序,然后只保留每组的第一条数据(也就是rn=1的那条)。要是想取组内id最小的,把ORDER BY id DESC改成ORDER BY id ASC就可以了。
内容的提问来源于stack exchange,提问作者Erwin Raharja
相关产品推荐
相关产品推荐

