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

如何在Laravel中查询关联关系完全匹配指定条件的数据集

实现方案

要实现关联完全匹配的查询逻辑,需要同时满足两个校验条件:

  1. 目标product_mappings关联的product_mapping_options必须包含所有传入的product_option_id
  2. 目标product_mappings关联的product_mapping_options不存在任何不在传入id集合中的值

修改后的查询作用域代码如下:

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\DB;

public function scopeProductOption(Builder $query, ...$productOptionTypeIds): Builder
{
    // 对传入id去重,避免重复参数干扰校验
    $targetIds = array_unique($productOptionTypeIds);
    $targetCount = count($targetIds);

    // 传入空数组时,返回没有关联任何option的mapping(可根据业务需求调整)
    if ($targetCount === 0) {
        return $query->whereDoesntHave('ProductMappingOptions');
    }

    // 原有逻辑:确保所有目标id都存在于关联中
    foreach ($targetIds as $id) {
        $query->whereHas('ProductMappingOptions', function (Builder $q) use ($id) {
            $q->where('product_option_id', $id);
        });
    }

    // 新增逻辑1:排除存在不在目标id集合中关联项的记录
    $query->whereDoesntHave('ProductMappingOptions', function (Builder $q) use ($targetIds) {
        $q->whereNotIn('product_option_id', $targetIds);
    });

    // 新增逻辑2:校验关联总数和目标id数量一致,避免同个mapping下有重复option id的异常场景
    $query->withCount('ProductMappingOptions')
        ->having('product_mapping_options_count', '=', $targetCount);

    return $query;
}

逻辑说明

  • 当传入[1,3,5]时,只会筛选出关联option id刚好是这三个、没有多余值的mapping,也就是示例里下标为0的条目
  • 当传入[1,3,5,9]时,只会筛选出关联option id刚好是这四个的条目,对应示例下标为3的条目
  • 双重校验(不存在额外id+数量匹配)可以覆盖绝大多数业务场景,包括同个mapping下重复关联同一个option id的异常情况

内容的提问来源于stack exchange,提问作者prodigy7

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 15:36:03