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

Eloquent多对多关联中实现双重WHERE IN查询

没问题,我来帮你用Eloquent多对多关联实现这个双重WHERE IN查询。首先得把模型间的关联定义清楚,然后再一步步实现符合需求的查询逻辑:

第一步:定义Eloquent多对多关联

假设你的核心模型是Element(对应elements表)和Stat(对应stuff_equipement_stats表),中间关联表是stuff_equipement_stats_elements。因为你的表主键不是Laravel默认的id,所以需要显式指定主键和关联参数:

在Element模型中:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Element extends Model
{
    protected $table = 'elements';
    protected $primaryKey = 'id_elements'; // 匹配你的表主键

    public function stats()
    {
        return $this->belongsToMany(
            Stat::class,
            'stuff_equipement_stats_elements', // 指定中间表名
            'id_elements', // 当前模型在中间表的外键
            'id_stats' // 关联模型在中间表的外键
        )->withPivot('id_elements', 'id_stats'); // 显式加载你需要的pivot字段,和原SQL返回一致
    }
}

在Stat模型中:

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Stat extends Model
{
    protected $table = 'stuff_equipement_stats';
    protected $primaryKey = 'id_stats';

    public function elements()
    {
        return $this->belongsToMany(
            Element::class,
            'stuff_equipement_stats_elements',
            'id_stats',
            'id_elements'
        )->withPivot('id_elements', 'id_stats');
    }
}
第二步:实现双重WHERE IN查询

这里的“双重WHERE IN”我分两种常见场景来讲解,你可以根据自己的实际需求选择:

场景1:主表字段 + 中间表字段的双重筛选

比如你想同时筛选:elements表的id_elements在指定集合里,且关联的id_stats在目标集合里的元素:

// 定义两个IN条件的集合
$targetStatsIds = [1, 4, 10, 12, 13, 15, 20, 21, 23, 29, 32];
$targetElementIds = [2, 5, 8, 10]; // 示例:你要筛选的元素ID集合

// 执行查询
$elements = Element::whereIn('id_elements', $targetElementIds)
    ->whereHas('stats', function ($query) use ($targetStatsIds) {
        // 过滤关联的stats ID在目标集合内
        $query->whereIn('id_stats', $targetStatsIds);
    })
    ->with(['stats' => function ($query) use ($targetStatsIds) {
        // 可选:如果只需要加载符合条件的stats关联数据,而非所有关联的stats
        $query->whereIn('id_stats', $targetStatsIds);
    }])
    ->get();

查询结果里的每个Element实例,都会包含符合条件的stats关联数据,且$element->stats[0]->pivot里会有id_stats和id_elements字段,和你原SQL返回的结构完全匹配。

场景2:中间表两个字段的双重筛选

如果你的需求是对中间表的两个字段同时做IN筛选(比如id_stats IN (...)且id_elements IN (...)),可以直接在whereHas的闭包里添加多个whereIn:

$targetStatsIds = [1, 4, 10, 12, 13, 15, 20, 21, 23, 29, 32];
$targetElementIdsInPivot = [2, 5, 8]; // 中间表中id_elements的目标集合

$elements = Element::whereHas('stats', function ($query) use ($targetStatsIds, $targetElementIdsInPivot) {
    $query->whereIn('id_stats', $targetStatsIds)
          ->whereIn('id_elements', $targetElementIdsInPivot);
})->with('stats')->get();
验证生成的SQL

如果你想确认Eloquent生成的SQL和你的需求一致,可以在查询构建完成后调用toSql()方法查看:

// 注意:要在get()之前调用toSql()
$sql = Element::whereIn('id_elements', $targetElementIds)
    ->whereHas('stats', function ($query) use ($targetStatsIds) {
        $query->whereIn('id_stats', $targetStatsIds);
    })
    ->toSql();

echo $sql;

这样就能看到生成的SQL语句,结构会和你原有的SQL匹配,同时包含双重IN的筛选条件。

内容的提问来源于stack exchange,提问作者Zeyukan Ich'

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:46:52