食堂管理应用Eloquent查询问题:无法正确获取指定月份用户数据
问题分析与解决方案
原查询的核心问题在于历史月份统计时,错误地将目标月份前已停用的用户也纳入了统计范围(比如2023年12月的查询会错误包含L用户)。原因是对inactive用户的筛选条件仅判断了创建/更新时间早于月底,未验证停用时间是否在目标月份范围内。
修正后的查询代码
$sessionDate = Carbon::createFromFormat('M-Y', session('dates')); $monthStart = $sessionDate->startOfMonth(); $monthEnd = $sessionDate->endOfMonth(); $currentDate = now(); $sessionDateNumeric = intval($sessionDate->format('Ym')); $currentDateNumeric = intval($currentDate->format('Ym')); if ($sessionDateNumeric == $currentDateNumeric) { // 当前月份:仅统计批次内活跃用户 $users = User::where('batch', $this->batch) ->where('status', 'active') ->get(); } elseif ($sessionDateNumeric < $currentDateNumeric) { // 历史月份:统计批次内、与目标月份存在交集的用户 $users = User::where('batch', $this->batch) ->where('created_at', '<=', $monthEnd) ->where(function ($query) use ($monthStart) { // 情况1:当前仍活跃(说明目标月份全程有效) $query->where('status', 'active') // 情况2:已停用,但停用时间在目标月份及之后(说明目标月份内存在过) ->orWhere(function ($query) use ($monthStart) { $query->where('status', 'inactive') ->where('updated_at', '>=', $monthStart); }); }) ->get(); } else { // 未来月份:返回空数组 $users = []; }
逻辑说明
- 当前月份:直接筛选批次内状态为
active的用户,符合需求。 - 历史月份:
- 先过滤掉目标月份结束后才创建的用户(
created_at <= $monthEnd)。 - 再分两类用户统计:
- 当前仍活跃的用户:这类用户从创建到现在一直有效,必然属于目标月份的成员。
- 已停用的用户:仅当其停用时间(
updated_at)晚于或等于目标月份开始时,才说明该用户在目标月份内存在过,需要纳入统计。
- 先过滤掉目标月份结束后才创建的用户(
结果验证
- 2023年10月:仅N用户符合(10月创建且活跃),正确。
- 2023年11月:N(活跃)、K(活跃)、L(11月内停用),共3位,正确。
- 2023年12月:M(12月创建活跃)、N(活跃)、K(活跃)、S(12月创建活跃),L因11月已停用被排除,共4位,正确。
- 2024年1月:所有活跃用户(M、N、K、S),共4位,正确。
内容的提问来源于stack exchange,提问作者MD Meadul Islam
相关产品推荐
相关产品推荐

