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

Laravel如何按学校ID统计特定数据?

Laravel按学校ID统计时段数据的正确实现

我来帮你梳理下这个统计需求的正确实现方式~首先得指出你当前代码里的小问题:

  • 你现在的$morning_session和$afternoon_session调用count()后,返回的是有多少个学校存在对应时段的学生,而不是每个学校各自的学生数量。
  • 多次分开查询数据库,效率偏低,我们可以合并成一次查询搞定。

下面给你几种实用的解决方案,按需选择:

方案一:一次Query Builder查询搞定双时段统计(推荐)

用CASE WHEN语法在一次查询中同时统计两个时段的学生数,还能通过左连接确保没有对应时段学生的学校也会被统计(数量为0):

$schoolSessionStats = DB::table('sekolah')
    ->leftJoin('pelajar', 'sekolah.sekolah_id', '=', 'pelajar.sekolah_id')
    ->select(
        'sekolah.sekolah_id',
        'sekolah.nama_sekolah', // 替换成你学校表的名称字段,不需要可以删掉
        DB::raw('COUNT(CASE WHEN pelajar.pelajar_sesi = "Morning" THEN 1 END) as morning_count'),
        DB::raw('COUNT(CASE WHEN pelajar.pelajar_sesi = "Afternoon" THEN 1 END) as afternoon_count')
    )
    ->groupBy('sekolah.sekolah_id', 'sekolah.nama_sekolah') // 分组字段要和select里的非聚合字段对应
    ->get();

拿到结果后,每个元素都会包含sekolah_id、morning_count和afternoon_count,直接遍历使用即可。

方案二:使用Eloquent关联统计(如果有模型的话)

如果你已经定义了Sekolah和Pelajar模型,用Eloquent的withCount方法会更简洁,代码可读性更高:

首先在Sekolah模型里定义关联:

// app/Models/Sekolah.php
public function pelajar()
{
    return $this->hasMany(Pelajar::class, 'sekolah_id');
}

然后执行统计查询:

$schools = Sekolah::withCount([
    'pelajar as morning_count' => function ($query) {
        $query->where('pelajar_sesi', 'Morning');
    },
    'pelajar as afternoon_count' => function ($query) {
        $query->where('pelajar_sesi', 'Afternoon');
    }
])->get();

这样每个Sekolah实例都会带上morning_count和afternoon_count两个属性,直接调用就行。

方案三:循环查询(不推荐,仅小数据量可用)

如果你的学校数量很少,也可以先获取所有学校,再逐个查询对应时段的学生数,但这种方法会产生N+1查询问题(N是学校数量),数据量大时性能很差:

$schools = DB::table('sekolah')->get();

foreach ($schools as $school) {
    $school->morning_count = DB::table('pelajar')
        ->where('sekolah_id', $school->sekolah_id)
        ->where('pelajar_sesi', 'Morning')
        ->count();
    
    $school->afternoon_count = DB::table('pelajar')
        ->where('sekolah_id', $school->sekolah_id)
        ->where('pelajar_sesi', 'Afternoon')
        ->count();
}

总结

优先选择方案一或方案二,它们只需要一次数据库查询,性能更优,代码也更简洁。如果项目用了Eloquent模型,方案二是最贴合Laravel风格的写法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:10:18