You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 15:52:47