Laravel:基于price/newprice字段的whereBetween条件查询问题
解决Laravel中基于price/newprice的区间筛选问题
你的问题核心出在逻辑条件的组合优先级错误,以及未按照需求区分newprice是否为0的筛选规则上。原代码里的orWhere会打乱整体逻辑,导致筛选结果不符合预期。
修正后的代码实现
$from = (int)$request->priceFrom; $to = (int)$request->priceTo; $products = Product::where(function ($query) use ($childCategories, $category) { // 把分类条件分组,确保这部分"或"逻辑是一个整体 $query->whereIn('category_id', $childCategories) ->orWhere('category_id', $category->id); }) ->where('publish', 1) ->where(function ($query) use ($from, $to) { // 核心价格筛选:二选一的互斥条件 $query->where(function ($subQuery) use ($from, $to) { // 无折扣时,按price区间筛选 $subQuery->where('newprice', 0) ->whereBetween('price', [$from, $to]); }) ->orWhere(function ($subQuery) use ($from, $to) { // 有折扣时,按newprice区间筛选 $subQuery->where('newprice', '!=', 0) ->whereBetween('newprice', [$from, $to]); }); }) ->orderBy('created_at', 'desc') ->paginate(15);
关键逻辑说明
- 分类条件分组:用外层闭包把分类的
whereIn和orWhere包起来,确保这部分逻辑是一个独立的整体,不会和后续的价格、发布状态条件产生逻辑冲突。 - 价格筛选的互斥逻辑:通过嵌套闭包实现两种互斥的筛选场景,严格遵循需求:
- 当商品无折扣(
newprice=0)时,用price字段做区间筛选 - 当商品有折扣(
newprice≠0)时,用newprice字段做区间筛选
- 当商品无折扣(
- 避免逻辑优先级混乱:Laravel查询构造器会自动为闭包逻辑添加SQL括号,保证每个条件组的优先级正确,不会出现原代码中"条件串味"的问题。
原代码失效的原因
原代码的逻辑会被解析成这样的SQL:(category_id IN (...) OR category_id = ...) AND publish = 1 AND price BETWEEN ... OR newprice BETWEEN ...
这种逻辑会把"newprice在区间但不满足分类/发布状态"的商品也查询出来,完全偏离了你的需求。
内容的提问来源于stack exchange,提问作者Saba Tandashvili
相关产品推荐
相关产品推荐

