Laravel中WHERE与AND拼接及含结束日期的日期范围查询实现
刚好之前也碰到过类似的问题,来给你梳理下解决方案:
1. Laravel中拼接WHERE和AND子句
在Laravel的查询构造器里,默认链式调用where()方法就是用AND来拼接条件的,比如:
$records = DB::table('orders') ->where('status', 'completed') ->where('total', '>', 100) ->get();
对应的SQL就是:
SELECT * FROM orders WHERE status = 'completed' AND total > 100;
这种写法完全等同于WHERE (status = 'completed') AND (total > 100)——因为AND是优先级相同的逻辑运算符,括号在这里不影响最终的查询逻辑。
如果你的条件里混合了OR,需要分组(用括号包裹)的话,就用闭包嵌套where():
$records = DB::table('orders') ->where('status', 'completed') ->where(function($query) { $query->where('total', '>', 100) ->orWhere('customer_id', 42); }) ->get();
这时候生成的SQL就会自动带上括号:
SELECT * FROM orders WHERE status = 'completed' AND (total > 100 OR customer_id = 42);
2. 解决whereBetween不包含结束日期的问题
你碰到的这个情况很常见,原因是created_at一般是datetime/timestamp类型,包含时分秒。如果你的$endDate是2024-05-20这种格式(不带时间),whereBetween会默认把它解析为2024-05-20 00:00:00,所以当天零点之后的记录都不会被包含。
有几种简单的解决办法:
- 方法一:用Carbon调整结束日期到当天最后一刻
Laravel自带Carbon日期库,直接调用endOfDay()就能把日期转为当天的23:59:59:
use Carbon\Carbon; $startingDate = '2024-05-01'; $endDate = Carbon::parse('2024-05-20')->endOfDay(); $records = DB::table('orders') ->whereBetween('created_at', [$startingDate, $endDate]) ->get();
- 方法二:直接用两个where条件精确控制范围
如果不想用Carbon,也可以手动拼接结束日期的时间:
$records = DB::table('orders') ->where('created_at', '>=', $startingDate) ->where('created_at', '<=', $endDate . ' 23:59:59') ->get();
- 方法三:只对比日期部分
如果不需要考虑具体时间,只关心日期是否在范围内,可以用whereDate()方法:
$records = DB::table('orders') ->whereDate('created_at', '>=', $startingDate) ->whereDate('created_at', '<=', $endDate) ->get();
这个方法会自动提取created_at的日期部分和你的参数对比,不管时分秒,自然就能包含结束日期当天的所有记录。
内容的提问来源于stack exchange,提问作者Gabriel Augusto
相关产品推荐
相关产品推荐

