Laravel 5.6 Query Builder中where/orWhere语句失效问题求助
解决方案:正确过滤直播试卷与往期试卷
看起来你遇到的核心问题是查询条件的逻辑分组错误,加上多余的条件干扰了结果,导致直播试卷的到期过滤不生效。我来帮你拆解问题并修复代码:
原查询的问题分析
- 冗余条件干扰:
where('papers.id','payments.paper_id')完全没必要——你已经通过join('payments','papers.id','=','payments.paper_id')关联了两张表,这个where语句写法本身也有问题(应该用whereColumn比较字段,但这里完全多余),反而可能导致数据过滤异常。 - 逻辑未分组:如果直接用
orWhere而不包裹在闭包里,会导致条件逻辑混乱,比如把“非直播试卷”和“直播未到期”的条件混在一起,无法正确过滤到期的直播试卷。
修正后的查询代码
假设你的papers表中:
- 直播试卷的
type值为Live,往期试卷为Normal; - 直播试卷有
end_time字段记录到期时间。
$curdate = Carbon::now(); $papers = DB::table('papers') ->join('payments', 'papers.id', '=', 'payments.paper_id') ->join('tutors', 'papers.tutor_id', '=', 'tutors.id') ->select('papers.*', 'tutors.name') // 用闭包分组条件,确保逻辑严谨 ->where(function ($query) use ($curdate) { // 条件1:所有往期试卷(Normal类型)直接展示 $query->where('papers.type', '=', 'Normal') // 条件2:直播试卷仅保留未到期的(end_time >= 当前时间) ->orWhere(function ($subQuery) use ($curdate) { $subQuery->where('papers.type', '=', 'Live') ->where('papers.end_time', '>=', $curdate); // 如果需要限制直播已开始,可额外添加: // ->where('papers.start_time', '<=', $curdate); }); }) ->get();
代码逻辑说明
- 外层闭包把两个核心条件包裹起来,确保查询返回的是要么是往期试卷,要么是未到期的直播试卷;
- 内层闭包针对直播试卷单独做时间判断,避免和其他条件产生逻辑冲突;
- 去掉了冗余的
where('papers.id','payments.paper_id'),让查询更高效且逻辑清晰。
如果你的papers表字段命名或类型定义有差异,只需调整对应的字段名称(比如把end_time改成你实际用的到期时间字段)即可。
内容的提问来源于stack exchange,提问作者Naveed Sheriffdeen
相关产品推荐
相关产品推荐

