Laravel 5.5如何用Eloquent获取按Name去重的最新数据行?
在Laravel 5.5中用Eloquent获取按Name去重的最新记录(PostgreSQL)
当然可以用Eloquent实现!针对PostgreSQL数据库,这里有两种实用的方案,我给你详细拆解:
方案一:子查询关联法(通用兼容)
这种方法不依赖PostgreSQL的特有语法,在其他数据库也能跑通。核心思路是先通过子查询拿到每个Name对应的最新created时间,再把这个结果和原表关联,筛选出符合条件的记录。
假设你的模型是Record,对应数据库表records,代码可以这么写:
$latestRecords = Record::query() ->select('records.*') ->join( DB::raw('(SELECT name, MAX(created) AS latest_created FROM records GROUP BY name) AS latest'), function ($join) { $join->on('records.name', '=', 'latest.name') ->on('records.created', '=', 'latest.latest_created'); } ) ->get();
这段代码先通过子查询分组计算每个Name的最新创建时间,再关联原表匹配对应的记录,最终得到每个Name的最新行。
方案二:PostgreSQL特有的DISTINCT ON语法(高效推荐)
PostgreSQL提供了DISTINCT ON语法,可以直接在查询中指定去重的字段,并且保留每组中排序后的第一条记录,效率比子查询更高。
需要注意的是,DISTINCT ON指定的字段必须是ORDER BY子句的第一个字段,所以我们先按name排序,再按created倒序,这样就能确保每个name组里取到最新的那条记录:
$latestRecords = Record::query() ->selectRaw('DISTINCT ON(name) *') ->orderBy('name') ->orderBy('created', 'desc') ->get();
注:如果尝试
->distinct('name')报错的话,就用上面的selectRaw写法,这是Laravel 5.5适配PostgreSQL的稳妥方式。
这个方案利用PostgreSQL的原生特性,查询性能更优,适合数据量较大的场景。
两种方案都能完美满足你的需求,你可以根据自己的实际情况选择~
内容的提问来源于stack exchange,提问作者derdida
相关产品推荐
相关产品推荐

