You need to enable JavaScript to run this app. Laravel 中Collection过滤已获取数据集计数返回0的问题求助
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 中Collection过滤已获取数据集计数返回0的问题求助

问题原因
  • 第一个过滤逻辑的错误:你SQL查询中whereIn('status',[1,4,6,7])作用的是关联模型bursaries.statuses的status字段,并非学生表本身的status字段。你在Collection层直接调用$students->where('status', '7')是尝试读取学生模型上的status属性,该属性不存在/无对应值,所以过滤结果为空。
  • 第二个过滤逻辑的错误:你直接读取$student->qualification,但qualification字段大概率不属于学生表,而是存在于你预加载的bursaries、enrolments、courses等关联模型中,读取不存在的属性返回null,自然匹配不到对应条件,计数为0。
  • 额外注意:Laravel Collection的where方法默认是严格类型匹配,如果目标status字段是数字类型,传字符串'7'也会导致匹配失败。
解决方法

1. 按关联属性过滤(无需修改原有查询)

如果需要保留原有查询逻辑,直接通过预加载的关联属性做过滤:

统计状态为7的学生数

$summary['students_transfer'] = $students->filter(function ($student) {
    // 判断学生关联的助学金状态中是否存在值为7的记录
    return $student->bursaries->pluck('statuses')->flatten()->contains('status', 7);
})->count();

统计研究生类学生数

假设qualification字段在bursaries表中,对应写法如下,若字段属于其他关联模型,修改层级即可:

$summary['students_postgraduate'] = $students->filter(function ($student) {
    return $student->bursaries->contains(function ($bursary) {
        return in_array($bursary->qualification, ['Postgraduate', 'Postgraduate in Training']);
    });
})->count();

2. 优化方案(查询时附加字段,提高过滤性能)

如果要降低Collection遍历关联的性能开销,可以在查询时就把需要的统计字段附加到学生模型上:

// 原有查询逻辑基础上修改
$students = $bursary_administrator->students()
    ->whereHas('bursaries.statuses', function($query) use ($request) {
        // 原有whereHas逻辑不变
        $query->whereIn('status',[1,4,6,7])
            ->whereYear('status_start','<=',$request->year)
            ->where(function ($query) use ($request){
                $query->whereYear('status_end','>=',$request->year)
                    ->orWhereNull('status_end');
            })
            ->where(function ($query) use ($request){
                $query->whereYear('registration_date','<=',$request->year)
                    ->orWhereNull('registration_date');
            });
    })
    // 附加需要的统计字段到学生模型,模型名请对应你项目的实际命名
    ->addSelect([
        'latest_bursary_status' => BursaryStatus::select('status')
            ->whereColumn('bursary_id', 'bursaries.id')
            ->latest('status_start')
            ->take(1),
        'qualification' => Bursary::select('qualification')
            ->whereColumn('student_id', 'students.id')
            ->take(1)
    ])
    ->with('bursaries','bursaries.statuses','bursaries.enrolments','bursaries.enrolments.courses')
    ->orderBy('student_name')
    ->orderBy('student_middle_names')
    ->orderBy('student_surname')
    ->get();

修改后就可以直接用简单的过滤写法:

$summary['students_transfer'] = $students->where('latest_bursary_status', 7)->count();
$summary['students_postgraduate'] = $students->whereIn('qualification', ['Postgraduate', 'Postgraduate in Training'])->count();

内容的提问来源于stack exchange,提问作者SupaMonkey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.08 08:57:03