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
相关产品推荐
相关产品推荐

