如何在Laravel中查询关联关系完全匹配指定条件的数据集
实现方案
要实现关联完全匹配的查询逻辑,需要同时满足两个校验条件:
- 目标
product_mappings关联的product_mapping_options必须包含所有传入的product_option_id - 目标
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
相关产品推荐
相关产品推荐

