Laravel 含日期范围与orWhere的Eloquent查询返回错误结果
问题根源
问题出在orWhere的条件优先级逻辑上。你当前的写法没有把两个OR查询分支(指定帖子下自己发的评论、作为所有者可见的评论)包裹在同一个顶层闭包内,后续追加的日期筛选条件只会绑定到最后一个orWhere分支,不会作用于整个OR逻辑的全量结果,实际运行的SQL逻辑等价于:
SELECT * FROM `comments` WHERE (`post_id` in (1,2) AND `user_id` = 2) OR (`is_owner` = 1 AND `deleted_at` IS NULL AND `created_at` >= '2022-07-13' AND `created_at` <= '2022-07-15') ORDER BY `created_at` DESC
这种逻辑下,只要是你在指定帖子下发布的评论,无论创建日期是否符合范围都会被返回,自然得不到预期结果。
修复方案
把所有OR相关的分支逻辑统一包裹在同一个顶层where闭包里,再在外层追加全局通用筛选条件(日期范围、软删标记等),保证全局条件作用于所有符合OR规则的结果集。
修复后的代码如下:
$comment = Comment::where(function ($query) use ($postIds, $userId, $isCommentOwner) { // 分支1:指定帖子下当前用户发布的评论 $query->where(function ($subQuery) use ($postIds, $userId) { $subQuery->whereIn('post_id', $postIds) ->where('user_id', $userId); }); // 分支2:当前用户作为所有者可见的评论 if ($isCommentOwner) { $query->orWhere(function ($subQuery) { $subQuery->where('is_owner', true); }); } }); // 全局日期筛选,作用于全量匹配结果 $comment->whereDate('created_at', '>=', '2022-07-13') ->whereDate('created_at', '<=', '2022-07-15'); // 后续排序、查询逻辑正常执行 $result = $comment->orderBy('created_at', 'desc')->get();
上述写法最终生成的SQL逻辑完全符合预期:
SELECT * FROM `comments` WHERE ( (`post_id` in (1,2) AND `user_id` = 2) OR (`is_owner` = 1) ) AND `deleted_at` IS NULL AND DATE(`created_at`) >= '2022-07-13' AND DATE(`created_at`) <= '2022-07-15' ORDER BY `created_at` DESC
对照你提供的测试数据,该查询会正确返回id为6、7的两条日期范围内的记录。
内容的提问来源于stack exchange,提问作者blitzen12
相关产品推荐
相关产品推荐

