如何在Laravel中使用ORM实现带whereIn的子查询
问题描述
我正在开发类社交网络功能,现有messages(消息)表、users(用户)表,以及存储用户关注关系的中间表,这些表的关联逻辑都能正常工作。我希望将以下SQL语句用Laravel ORM实现:
SELECT * FROM mensajes
WHERE user_id=1
OR user_id IN (SELECT seguido_id FROM seguidos WHERE user_id=1)
需求是获取当前用户的消息,以及其关注用户的消息。我现有方案可行但不够优雅,想改用子查询实现:
现有可行但不够优雅的代码
// 该关联关系返回当前用户关注的用户,可正常工作 $seguidos = auth()->user()->seguidos; // 存储关注用户的ID数组 $seg = []; foreach ($seguidos as $s) { array_push($seg, $s->id); } array_push($seg, auth()->user()->id); // 获取这些用户的所有消息(包含自身) $this->mensajes = Mensaje::whereIn('user_id', $seg) ->orderBy('created_at', 'desc') ->get();
尝试子查询但遇到疑问
$this->mensajes = Mensaje::where('user_id', auth()->user()->id) ->orWhereIn('user_id', function($query) { // ... 此处应如何编写? // $query = auth()->user()->seguidos->select('id'); // 这样当然不行 } ->orderBy('created_at', 'desc') ->get();
解决方案
你可以通过以下几种方式实现子查询写法:
方式一:直接构建子查询
在闭包内直接编写对应SQL的子查询逻辑:
$this->mensajes = Mensaje::where('user_id', auth()->user()->id) ->orWhereIn('user_id', function ($query) { // 子查询:获取当前用户关注的所有用户ID(对应seguido_id) $query->select('seguido_id') ->from('seguidos') ->where('user_id', auth()->user()->id); }) ->orderBy('created_at', 'desc') ->get();
方式二:利用模型关联生成子查询
如果你的User模型已经定义了seguidos关联(比如hasMany或belongsToMany),可以直接借助关联的查询构造器生成子查询,注意要使用seguidos()(带括号,返回查询构造器实例)而非seguidos(不带括号,返回已加载的集合):
$this->mensajes = Mensaje::where('user_id', auth()->user()->id) ->orWhereIn('user_id', auth()->user()->seguidos()->select('id')) ->orderBy('created_at', 'desc') ->get();
方式三:合并自身ID与子查询
用union将自身ID和关注用户ID的子查询合并,统一用whereIn处理:
$this->mensajes = Mensaje::whereIn('user_id', function ($query) { $query->select('seguido_id') ->from('seguidos') ->where('user_id', auth()->user()->id) ->union(DB::raw("SELECT ".auth()->user()->id)); }) ->orderBy('created_at', 'desc') ->get();
补充:简化原有方案(非子查询但更优雅)
如果不想用子查询,也可以用pluck替代循环生成ID数组:
$userIds = auth()->user()->seguidos()->pluck('id')->push(auth()->user()->id); $this->mensajes = Mensaje::whereIn('user_id', $userIds) ->orderBy('created_at', 'desc') ->get();
内容的提问来源于stack exchange,提问作者luisfer
相关产品推荐
相关产品推荐

