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

Laravel中如何根据数组长度动态生成关联查询条件筛选Pub

如何在Laravel中动态筛选关联所有指定Tapp的Pub模型?

你之前遇到的问题其实很典型——在单个whereHas里循环添加where('tapp_id', $tappId),相当于要求同一条中间表记录的tapp_id同时等于多个值,这显然是不可能的,所以才会返回空数组。

下面给你两种可行的解决方案,适配任意长度的tapp_id数组:

方法一:动态叠加whereHas查询

这个思路和你一开始用固定长度数组时的逻辑一致,只不过改成动态循环生成每个tapp_id的检查条件:

$tapps_chosen = [5, 8, 7];
$query = Pub::query();

// 遍历每个tapp_id,为每个id添加一个whereHas条件
foreach ($tapps_chosen as $tappId) {
    $query->whereHas('pubTapps', function ($q) use ($tappId) {
        $q->where('tapp_id', $tappId);
    });
}

$pubs = $query->get();

每个whereHas都会验证当前Pub是否关联了对应的Tapp,多个whereHas叠加就是逻辑“与”的关系,最终只会返回同时关联所有指定Tapp的Pub。这种方法逻辑直观,适合数组长度不大的场景。

方法二:使用分组+统计筛选

如果你的tapp_id数组比较长,多次whereHas可能会生成较多的子查询,这时可以用分组统计的方式优化:

$tapps_chosen = [5, 8, 7];
$requiredCount = count($tapps_chosen);

$pubs = Pub::whereHas('pubTapps', function ($query) use ($tapps_chosen, $requiredCount) {
    $query->whereIn('tapp_id', $tapps_chosen)
          ->groupBy('pub_id')
          ->havingRaw('COUNT(DISTINCT tapp_id) = ?', [$requiredCount]);
})->get();

这个逻辑是:

  1. 先筛选出关联的Tapp在指定数组中的记录
  2. 按pub_id分组,统计每个Pub关联的不同Tapp数量
  3. 只保留数量等于数组长度的分组——这就意味着该Pub关联了所有指定的Tapp

这种方法只需要一次子查询,性能更优,适合数组较长的场景。

为什么你之前的代码无效?

再强调一下:你之前在单个whereHas里循环添加where条件,生成的SQL类似WHERE tapp_id = 5 AND tapp_id = 8 AND tapp_id =7,这要求单条pub_tapps记录同时满足多个tapp_id,显然不存在这样的记录,所以返回空数组。

内容的提问来源于stack exchange,提问作者Ber Tsacianegu del Tepuy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:42:41