基于Eloquent关联筛选Model A数据的两类查询需求
Laravel Eloquent 关联查询解决方案
1. 获取所有关联的每一个Model B都存在非空title的Model C的Model A
要实现这个需求,需确保Model A的每一个关联B都存在对应的C,且C的title字段不为空。可通过排除法筛选出不存在任何不符合条件的B的A:
use Illuminate\Support\Facades\DB; // 写法1:基于原生查询构造器的排除逻辑 $validAs = A::whereDoesntExist(function ($query) { $query->select(DB::raw(1)) ->from('bs') ->whereColumn('bs.a_id', 'as.id') ->where(function ($subQuery) { // 匹配两种不符合条件的情况:B无关联C,或关联的C title为空 $subQuery->whereDoesntExist(function ($cQuery) { $cQuery->select(DB::raw(1)) ->from('cs') ->whereColumn('cs.b_id', 'bs.id'); })->orWhereExists(function ($cQuery) { $cQuery->select(DB::raw(1)) ->from('cs') ->whereColumn('cs.b_id', 'bs.id') ->whereNull('cs.title'); }); }); })->get(); // 写法2:利用Eloquent关联的简洁写法 $validAs = A::whereHas('b', function ($bQuery) { // 筛选出“没有非空title的C”的B $bQuery->whereDoesntExist(function ($cQuery) { $cQuery->from('cs') ->whereColumn('cs.b_id', 'bs.id') ->whereNotNull('title'); }); }, '=', 0)->get();
针对示例数据,以上查询仅返回id=1的Model A,因为它的所有关联B都对应着非空title的C。
2. 获取所有关联的Model B中至少有一个存在空title的Model C的Model A
这个需求只需验证Model A是否存在至少一个关联B,该B对应的C的title字段为空,直接通过whereHas嵌套关联即可实现:
$invalidAs = A::whereHas('b.c', function ($cQuery) { $cQuery->whereNull('title'); })->get();
逻辑说明:whereHas('b.c')会检查A的关联B中,是否存在至少一个B的关联C满足title is null的条件。针对示例数据,该查询仅返回id=2的Model A。
内容的提问来源于stack exchange,提问作者eloelo530
相关产品推荐
相关产品推荐

