Laravel 8中实现whereNot功能的替代方案求助
Laravel 8 替代 whereNot 实现排除特定条件的查询方案
需求回顾
需要排除同时满足stock=0且stock_date早于一个月的产品;若stock=0但stock_date未超过一个月,该产品仍需保留。Laravel 9新增的whereNot方法无法在Laravel 8中使用,以下是两种可行的替代实现:
方案1:使用whereRaw直接映射原生SQL逻辑
这种方式最贴近你提供的原生MySQL语句,逻辑直观且避免SQL注入:
use Carbon\Carbon; $query = Product::select('id') ->where('status', 1) ->where('type', 1) ->whereRaw('NOT (stock = 0 AND stock_date < ?)', [Carbon::now()->subMonths(1)]);
通过whereRaw直接嵌入NOT条件,并通过参数绑定传递日期值,和原生SQL的逻辑完全一致。
方案2:利用逻辑等价转换(德摩根定律)
根据逻辑运算规则,NOT (A AND B) 等价于 NOT A OR NOT B,我们可以用Laravel查询构造器的原生方法实现,无需依赖whereNot:
use Carbon\Carbon; $oneMonthAgo = Carbon::now()->subMonths(1); $query = Product::select('id') ->where('status', 1) ->where('type', 1) ->where(function ($q) use ($oneMonthAgo) { $q->where('stock', '!=', 0) ->orWhere('stock_date', '>=', $oneMonthAgo); });
把需要排除的条件反转:要么库存不为0,要么库存为0但日期未超过一个月,用闭包包裹这两个OR条件,最终效果和Laravel 9的whereNot写法完全一致。
验证对比
两种方案最终生成的SQL都和你提供的原生语句等价,确保只排除同时满足两个条件的产品,符合需求要求。
内容的提问来源于stack exchange,提问作者Cudos
相关产品推荐
相关产品推荐

