Laravel Eloquent如何获取同时经B、C表关联A表的D表模型
当然可以实现!
根据你的数据库结构和需求,我们可以通过Laravel Eloquent的多种查询方式来获取符合条件的D模型。先明确一下关联逻辑(假设你的模型命名为A、B、C、D,且外键命名符合示例中的规则,比如B表的A_idA对应A的idA,D表有B_idB和C_idC分别关联B和C):
场景1:D只需关联到任意A(通过B)且关联到任意A(通过C)
如果你的需求是D只要能通过B关联到某个A,同时能通过C关联到某个A(两个A可以不同),直接用whereHas嵌套关联查询即可:
$dModels = D::whereHas('b.a') ->whereHas('c.a') ->get();
这里的前提是你的模型已经定义了正确的关联:
B模型:public function a() { return $this->belongsTo(A::class, 'A_idA'); }C模型:public function a() { return $this->belongsTo(A::class, 'A_idA'); }D模型:public function b() { return $this->belongsTo(B::class, 'B_idB'); }D模型:public function c() { return $this->belongsTo(C::class, 'C_idC'); }
场景2:D关联的B和C必须属于同一个A
如果你的需求更严格——D对应的B和C必须关联到同一个A,可以用以下两种方式实现:
方法一:使用Join查询
use Illuminate\Support\Facades\DB; $dModels = D::join('b', 'd.B_idB', '=', 'b.idB') ->join('a', 'b.A_idA', '=', 'a.idA') ->join('c', 'a.idA', '=', 'c.A_idA') ->whereColumn('d.C_idC', '=', 'c.idC') ->select('d.*') // 只选择D表的字段,避免冗余 ->distinct() // 去重,防止同一D被多次匹配 ->get();
方法二:使用WhereExists子查询
这种方式更贴合Eloquent的关联思维,性能表现也很稳定:
use Illuminate\Support\Facades\DB; $dModels = D::whereExists(function ($query) { $query->select(DB::raw(1)) ->from('b') ->join('a', 'b.A_idA', '=', 'a.idA') ->join('c', 'a.idA', '=', 'c.A_idA') ->whereColumn('b.idB', '=', 'd.B_idB') ->whereColumn('c.idC', '=', 'd.C_idC'); })->get();
这两种方法都会筛选出那些同时关联到属于同一个A的B和C的D记录,比如在你的示例数据中,如果D有一条记录关联B1(属于A1)和C1(属于A1),它会被选中;但如果D关联B1和C2(属于A2),则不会被选中。
内容的提问来源于stack exchange,提问作者Marko H.
相关产品推荐
相关产品推荐

