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

Laravel whereHas查询返回全部记录 如何按属性值过滤商品变体

错误原因说明
  • 首次代码问题:
    你写的whereHas关联是商品的属性值,whereIn逻辑是只要商品存在任意一个匹配的属性值就算符合条件,自然会返回当前商品的所有变体。另外还有两个低级错误:一是变量名拼写错误$poruduct_id,二是如果$value_ids是逗号分隔的字符串,直接套[$value_ids]会生成只有一个字符串元素的数组,无法正确匹配多个值。
  • 第二次优化的问题:
    你按product_id分组统计,统计维度是商品,还是没有绑定到变体本身的属性,所以筛选不出符合要求的变体。
可行解决方案

下面两种方案都可以实现需求:

方案一:SKU编码匹配(你最终采用的方案优化版)

修复你原有代码里的变量重复定义、未定义问题,简化匹配逻辑:

// 取请求参数
$product_id = $request->product_id;
$value_codes = $request->value_codes;
// 拆分编码为数组,过滤空值
$searchValues = preg_split('/,/', $value_codes, -1, PREG_SPLIT_NO_EMPTY);

$variants = Variant::where(function ($q) use ($searchValues) {
    foreach ($searchValues as $value) {
        // 正则匹配确保不会命中其他编码的子串
        $q->orWhereRaw('sku REGEXP ?', ["(^|-)${value}(-|$)"]);
    }
})
->where('product_id', $product_id)
->get();

dd($variants);

该方案性能高,只要SKU命名规则统一,比如属性编码之间用-分隔,就可以稳定使用。

方案二:关联查询精准匹配

如果不想依赖SKU规则,可以调整关联后查询:
首先给Variant模型添加和属性值的关联,再循环添加whereHas条件,要求变体满足所有指定的属性值:

$value_ids = explode(',', $request->value_ids);
$product_id = $request->product_id;

$variants = Variant::where('product_id', $product_id)
    ->where(function ($query) use ($value_ids) {
        foreach ($value_ids as $vid) {
            $query->whereHas('attributeValues', function ($q) use ($vid) {
                $q->where('value_id', $vid);
            });
        }
    })
    ->get();

dd($variants);

该方案灵活性更高,不需要约束SKU的命名规则。


内容的提问来源于stack exchange,提问作者Mehmet İMAL

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 17:39:02