Laravel按用户分组查询工厂消息时如何获取每组最新message_text
解决方案
你可以通过分组拼接取首值或者子查询两种方式实现需求,以下是适配你现有代码的修正方案:
return Messages::where('factory_id', '=', 27) ->select( 'user_id', DB::raw('COUNT(*) as total'), // 按消息ID倒序拼接后取第一条,即为最新消息内容 DB::raw('SUBSTRING_INDEX(GROUP_CONCAT(message_text ORDER BY id DESC SEPARATOR "|||"), "|||", 1) as latest_message') ) ->groupBy('user_id') ->with(['user' => function($query) { // 对齐users表的字段名profile_pic $query->select('id', 'name', 'profile_pic'); }]) ->get();
关键说明
- 你原有代码中的
leftjoin('users')属于冗余逻辑,with预加载已经会单独拉取关联用户数据,无需额外连表。 GROUP_CONCAT默认拼接分隔符是逗号,如果你的消息内容可能包含逗号,可以自定义SEPARATOR为非常用字符避免截断错误。- 注意你原有预加载语句中写的
profilepic和users表实际字段profile_pic不一致,需要修正才能正常获取头像字段。
大数据量优化方案(Laravel 6+支持)
如果消息表数据量较大,使用子查询的方式性能更好:
return Messages::where('factory_id', 27) ->select('user_id', DB::raw('COUNT(*) as total')) ->addSelect(['latest_message' => Message::select('message_text') ->whereColumn('user_id', 'messages.user_id') ->where('factory_id', 27) ->latest('id') ->take(1) ]) ->groupBy('user_id') // 简化预加载字段写法 ->with('user:id,name,profile_pic') ->get();
内容的提问来源于stack exchange,提问作者reza haj rahimi
相关产品推荐
相关产品推荐

