Laravel中如何同时使用whereNull与orWhereBetween实现查询筛选
问题原因
你当前的查询逻辑存在逻辑运算符优先级问题:
原代码生成的SQL等价于
SELECT * FROM docs WHERE payment_status IS NULL OR value_date BETWEEN ? AND ? OR pmt_msg_date BETWEEN ? AND ? OR acceptance_date BETWEEN ? AND ?
四个条件只要满足任意一个就会被返回,所以自然会出现payment_status不为空但符合日期范围的记录,和你需要的「payment_status必须为null,且三个日期字段任意一个落在区间内」的逻辑不符。
修复方案
使用Laravel的条件分组查询,把三个日期的OR条件放到一个闭包分组中,和whereNull('payment_status')形成AND关系,修正后的代码如下:
function payment_list_table(Request $req) { if (session()->has('user')) { // 可先加参数校验,避免日期格式错误 $req->validate([ 'from' => 'required|date', 'to' => 'required|date|after_or_equal:from' ]); $data = Doc::whereNull('payment_status') ->where(function ($query) use ($req) { $query->whereBetween('value_date', [$req->from, $req->to]) ->orWhereBetween('pmt_msg_date', [$req->from, $req->to]) ->orWhereBetween('acceptance_date', [$req->from, $req->to]); }) ->get(); return view('payment/table_payment_list', ['datas'=>$data]); } // 未登录分支建议补充跳转逻辑,示例: // return redirect()->route('login')->with('error', '请先登录'); }
修正后生成的SQL等价于
SELECT * FROM docs WHERE payment_status IS NULL AND (value_date BETWEEN ? AND ? OR pmt_msg_date BETWEEN ? AND ? OR acceptance_date BETWEEN ? AND ?)
完全匹配你的筛选需求。
补充说明
建议给日期参数加上校验逻辑,避免用户输入非法日期格式、起始日期晚于结束日期等异常场景,保证查询稳定性。
内容的提问来源于stack exchange,提问作者sudeep Acharya
相关产品推荐
相关产品推荐

