You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel按ward_id统计学校学生数接口逻辑修复与优化

Laravel辖区学校学生统计接口修复方案

前置依赖检查

先确认各模型关联已按层级正确定义,否则聚合统计无法生效:

  • Ward模型定义hasMany关联到School
  • School模型定义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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 00:42:14