Laravel按ward_id统计学校学生数接口逻辑修复与优化
Laravel辖区学校学生统计接口修复方案
前置依赖检查
先确认各模型关联已按层级正确定义,否则聚合统计无法生效:
Ward模型定义hasMany关联到SchoolSchool模型定义hasMany关联到Grade:
// School.php public function grades() { return $this->hasMany(Grade::class); }
Grade模型定义hasMany关联到Stream:
// Grade.php public function streams() { return $this->hasMany(Stream::class); }
Stream模型定义hasMany关联到Student:
// Stream.php public function students() { return $this->hasMany(Student::class); }
控制器方法实现
放弃四层嵌套循环遍历的写法,直接用数据库层聚合查询完成统计,避免内存占用和统计错误,接口地址保持原有/api/getSchools/{ward_id}不变:
// WardController.php public function getSchoolsinWard($ward_id) { // 校验辖区是否存在 $ward = Ward::find($ward_id); if (!$ward) { return response()->json([ 'message' => '指定辖区不存在' ], 404); } // 查询学校列表+聚合统计,仅返回需要的字段,不加载全量关联数据 $schools = School::where('ward_id', $ward_id) ->select('id', 'name', 'ward_id', 'address') // 按需保留学校基础字段,不需要的字段不要查 ->withCount([ // 单校总学生数,通过多层关联一次性聚合 'grades.streams.students as total_students', // 单校男生数,加性别条件过滤 'grades.streams.students as total_boys' => function ($query) { $query->where('gender', 'male'); }, // 单校女生数,加性别条件过滤 'grades.streams.students as total_girls' => function ($query) { $query->where('gender', 'female'); } ]) ->get(); // 计算辖区维度汇总值 $totalSchools = $schools->count(); $totalStudentsInWard = $schools->sum('total_students'); // 按要求结构返回响应 return response()->json([ 'message' => '查询成功', 'total_students_in_wards' => $totalStudentsInWard, 'total_schools' => $totalSchools, 'schools' => $schools ], 200); }
对应问题修复说明
- 统计逻辑错误修复:所有计数由数据库SQL聚合完成,不存在循环遍历覆盖变量的问题,统计结果准确,同时避免了循环查询产生的N+1性能问题。
- 冗余数据清理:查询时仅指定返回学校基础字段,不加载grades、streams、students的全量关联数据,响应体无多余层级。
- 返回结构校准:严格匹配要求格式,顶层返回
message、total_students_in_wards、total_schools字段,schools数组内每个元素仅保留学校基础字段+total_students、total_boys、total_girls三个统计字段。
响应示例
{ "message": "查询成功", "total_students_in_wards": 13620, "total_schools": 14, "schools": [ { "id": 1, "name": "辖区第一中心小学", "ward_id": 5, "address": "辖区中心路1号", "total_students": 1240, "total_boys": 647, "total_girls": 593 }, { "id": 2, "name": "辖区第二初级中学", "ward_id": 5, "address": "辖区教育路27号", "total_students": 986, "total_boys": 512, "total_girls": 474 } ] }
内容的提问来源于stack exchange,提问作者deo_gemini
相关产品推荐
相关产品推荐

