Laravel如何合并两个不同数据库查询并获取结果?
需求与问题
需要从数据库中获取某篇帖子的总点赞数,以及当前用户对该帖子的点赞数,希望将两个独立查询合并为一次数据库请求。
尝试了以下代码:
$userId = auth('sanctum')->user()->id; $userLikesCountQuery = DB::table("likes") ->select('SUM(like) as user_count') ->where('user_id', $userId); $data = DB::table("likes") ->select( DB::raw('SUM(like) as count'), $userLikesCountQuery, ) ->first(); return [ 'meta' => [ 'count' => $data->count ?? 0, 'user_count' => $data->user_count ?? 0, ], ];
运行后出现错误:
stripos(): Argument #1 ($haystack) must be of type string, Illuminate\Database\Query\Builder given
解决方案
方法一:修复子查询的传入方式
你不能直接将Query Builder实例传入select方法,需要将其转换为子查询字符串并绑定参数,避免SQL注入:
$userId = auth('sanctum')->user()->id; $postId = // 替换为目标帖子ID // 构建用户点赞数的子查询,必须加上帖子ID筛选 $userLikesCountQuery = DB::table("likes") ->selectRaw('SUM(`like`) as user_count') ->where('user_id', $userId) ->where('post_id', $postId); $data = DB::table("likes") ->select( DB::raw('SUM(`like`) as count'), DB::raw("({$userLikesCountQuery->toSql()}) as user_count") ) ->where('post_id', $postId) // 筛选当前帖子的点赞 ->mergeBindings($userLikesCountQuery) // 绑定子查询的参数 ->first(); return [ 'meta' => [ 'count' => $data->count ?? 0, 'user_count' => $data->user_count ?? 0, ], ];
方法二:条件聚合(更简洁推荐)
不需要子查询,直接用CASE WHEN在一次聚合中同时计算两个值:
$userId = auth('sanctum')->user()->id; $postId = // 替换为目标帖子ID $data = DB::table("likes") ->select( DB::raw('SUM(`like`) as count'), DB::raw('SUM(CASE WHEN user_id = ? THEN `like` ELSE 0 END) as user_count', [$userId]) ) ->where('post_id', $postId) ->first(); return [ 'meta' => [ 'count' => $data->count ?? 0, 'user_count' => $data->user_count ?? 0, ], ];
方法三:Eloquent模型关联方式
如果项目中使用了Eloquent模型,可通过关联统计实现:
// Post模型中定义点赞关联 public function likes() { return $this->hasMany(Like::class); } // 查询时 $userId = auth('sanctum')->user()->id; $post = Post::where('id', $postId) ->withCount([ 'likes as count' => function ($query) { $query->select(DB::raw('SUM(`like`)')); }, 'likes as user_count' => function ($query) use ($userId) { $query->select(DB::raw('SUM(`like`)'))->where('user_id', $userId); } ]) ->first(); return [ 'meta' => [ 'count' => $post->count ?? 0, 'user_count' => $post->user_count ?? 0, ], ];
内容的提问来源于stack exchange,提问作者Eleandro Duzentos
相关产品推荐
相关产品推荐

