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

Laravel Eloquent查询orWhere子句未正确过滤已存在商品问题求助

问题根源

你的查询问题出在SQL逻辑运算符优先级上:SQL中AND的优先级高于OR,你原来的写法生成的SQL逻辑等价于:

WHERE status = 'activo'
AND id NOT IN (子查询)
AND nombre like '%xxx%'
OR codigo_interno like '%xxx%'
OR codigo_comercial like '%xxx%'

也就是说当搜索codigo_interno或者codigo_comercial匹配时,不管前面的status限制、id NOT IN排除已加商品的限制是否生效,只要这两个字段匹配就会被查出来,这就是你看到已加入列表的商品仍然出现的原因。

修复方案

你需要把三个模糊搜索的条件用分组闭包包裹,让这三个OR条件作为一个整体,和前面的过滤条件是AND的关系,修正后的代码如下:

public function findArticulo(Request $request)
{
    $id = $request->id;
    $busqueda = '%'.$request->busqueda.'%';

    $articulos = Articulo::query()->select([
            'id',
            'codigo_interno',
            'codigo_comercial',
            'impuestos_venta',
            'impuestos_compra',
            'nombre',
            'descripcion',
            'status'
        ])
        ->where('status','activo')
        ->whereNotIn('id', function($query)use($id){
            $query->select('articulo_id')
                ->from('listas_precios_articulos')
                ->where('lista_precio_id', $id)
                ->whereNotIn('estatus', ['eliminado']);
        })
        // 把三个OR搜索条件放到同一个分组里
        ->where(function($query) use ($busqueda) {
            $query->where('nombre' , 'like' , $busqueda)
                ->orWhere('codigo_interno' , 'like' , $busqueda)
                ->orWhere('codigo_comercial' , 'like' , $busqueda);
        })
        ->get()
        ->toArray();

    return response()->json($articulos,200);
}

修改后生成的SQL逻辑等价于:

WHERE status = 'activo'
AND id NOT IN (子查询)
AND (
    nombre like '%xxx%'
    OR codigo_interno like '%xxx%'
    OR codigo_comercial like '%xxx%'
)

这样不管搜索三个字段中的哪一个,都会先满足「状态是激活、未加入当前价目表」的前置条件,符合你的业务需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 17:48:08