如何在多对多关联中间表中根据多个属性值查询SKU ID
问题描述
现有SKU表与attribute_value表通过中间表建立多对多关联,表结构及数据如下:
SKU表
| id | code |
|---|---|
| 1 | sku1 |
| 2 | sku2 |
| 3 | sku3 |
Attribute value表
| id | name |
|---|---|
| 1 | 红色 |
| 2 | 蓝色 |
| 3 | 黑色 |
| 4 | 粉色 |
| 5 | 大号 |
| 6 | 小号 |
中间表(sh_sku_attribute)
| id | sku_id | att_value |
|---|---|---|
| 1 | 1 | 2 |
| 2 | 1 | 5 |
| 3 | 2 | 2 |
| 4 | 2 | 6 |
| 5 | 3 | 3 |
| 6 | 3 | 6 |
需求:已知两个属性值ID(如2和6,对应蓝色和小号),查询同时拥有这两个属性的SKU ID。
用户现有Laravel查询代码:
Sku::whereHas('Attributevalue', function ($query) { $query->whereIn('sh_sku_attribute.attribute_id',[2,6] ) ; })->first() ;
正确实现方法
原代码的问题在于whereIn只会筛选出拥有其中任意一个属性的SKU,无法保证同时拥有所有指定属性。要实现同时匹配多个属性的查询,可通过以下两种方式实现:
方法一:多次调用whereHas
针对每个属性ID分别添加whereHas条件,确保SKU同时关联所有指定属性:
$attributeIds = [2, 6]; $skuQuery = Sku::query(); foreach ($attributeIds as $id) { $skuQuery->whereHas('Attributevalue', function ($query) use ($id) { $query->where('sh_sku_attribute.att_value', $id); }); } // 获取所有符合条件的SKU,若只需第一个则替换为->first() $result = $skuQuery->get();
方法二:分组统计匹配数量
通过中间表分组,统计每个SKU匹配的属性数量,筛选出数量等于指定属性总数的SKU:
$attributeIds = [2, 6]; // 先获取符合条件的SKU ID集合 $skuIds = DB::table('sh_sku_attribute') ->whereIn('att_value', $attributeIds) ->groupBy('sku_id') ->havingRaw('COUNT(DISTINCT att_value) = ?', [count($attributeIds)]) ->pluck('sku_id'); // 若需要获取完整的SKU模型 $skus = Sku::whereIn('id', $skuIds)->get();
关键注意点
- 确保Sku模型中定义了正确的多对多关联:
// Sku.php public function Attributevalue() { return $this->belongsToMany(Attributevalue::class, 'sh_sku_attribute', 'sku_id', 'att_value'); }
- 原代码中误用了中间表字段名,实际中间表存储属性值ID的字段是
att_value,而非attribute_id,需修正。
内容的提问来源于stack exchange,提问作者Saeed M
相关产品推荐
相关产品推荐

