Laravel Eloquent:跨表数据检索比较及关联表where条件查询问题
我来帮你搞定这两个Laravel Eloquent的常见问题,都是日常开发里经常碰到的场景~
问题1:从table1检索数据,基于table2的条件比较
首先得假设你的两个表之间有关联(比如一对多、一对一),咱们拿常见的posts(table1)和comments(table2)举例,Post模型已经定义了comments关联(hasMany(Comment::class)),下面给你几种常用的实现方式:
方法1:使用whereHas(推荐,利用模型关联)
这个方法专门用来过滤主模型,只保留那些存在符合条件关联记录的主模型数据:
// 获取所有存在「已通过审核」评论的文章 $posts = Post::whereHas('comments', function ($query) { $query->where('status', 'approved'); })->get(); // 更复杂的比较:获取存在「点赞数大于10」评论的文章 $posts = Post::whereHas('comments', function ($query) { $query->where('likes_count', '>', 10); })->get();
方法2:使用join(适合未定义关联或需要灵活连接的场景)
如果你的模型没定义关联,或者需要更自定义的表连接逻辑,可以用DB门面的join方法:
$posts = DB::table('posts') ->join('comments', 'posts.id', '=', 'comments.post_id') ->where('comments.status', 'approved') ->select('posts.*') // 只获取table1的所有字段 ->distinct() // 避免因为多条关联数据导致主模型重复 ->get();
方法3:使用whereExists(存在性检查,性能友好)
如果只是要检查table2中是否存在符合条件的记录,用whereExists会更高效:
$posts = Post::whereExists(function ($query) { $query->select(DB::raw(1)) ->from('comments') ->whereColumn('comments.post_id', 'posts.id') ->where('comments.status', 'approved'); })->get();
问题2:给
with关联的表添加where条件校验 这里要分两种常见场景,别搞混了:
场景1:过滤主模型+加载符合条件的关联数据
如果你想只保留那些有符合条件关联的主模型,同时加载这些符合条件的关联数据,需要把whereHas和with结合起来用:
// 获取所有有「已通过审核」评论的文章,并且只加载这些已通过的评论 $posts = Post::whereHas('comments', function ($query) { $query->where('status', 'approved'); })->with(['comments' => function ($query) { $query->where('status', 'approved'); }])->get();
场景2:保留所有主模型,只加载符合条件的关联数据
如果你想返回所有主模型,但关联数据只取符合条件的(没有符合条件关联的主模型,关联字段会是空数组),直接在with的闭包里加条件就行:
// 获取所有文章,但只加载其中「已通过审核」的评论 $posts = Post::with(['comments' => function ($query) { $query->where('status', 'approved'); }])->get(); // 多条件示例:加载最近一周内的已通过评论 $posts = Post::with(['comments' => function ($query) { $query->where('status', 'approved') ->where('created_at', '>=', now()->subWeek()); }])->get();
内容的提问来源于stack exchange,提问作者Murlidhar Fichadia
相关产品推荐
相关产品推荐

