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

Laravel中Join、Sum与Group by查询求和值超出预期问题

解决Laravel中数据库查询求和结果超出预期的问题

原查询的问题在于:institutes和enrollements是一对多关联,直接join会生成重复的enrollements记录,执行sum时会重复累加同一机构的男女数,导致结果偏大。

修正后的查询代码(DB门面方式)

$dist_total_gender = DB::table('institutes')
    // 先子查询统计每个机构的男女总数,避免重复行
    ->join(DB::raw('(
        SELECT form_id, 
               SUM(total_boys) AS institute_total_boys, 
               SUM(total_girls) AS institute_total_girls
        FROM enrollements
        GROUP BY form_id
    ) AS enrollement_totals'), function($join) {
        $join->on('enrollement_totals.form_id', '=', 'institutes.form_id');
    })
    ->join('Geographies', 'institutes.district', '=', 'Geographies.id')
    ->groupBy('institutes.district', 'Geographies.name')
    ->select(
        DB::raw('SUM(enrollement_totals.institute_total_boys) AS Total_Boys'),
        DB::raw('SUM(enrollement_totals.institute_total_girls) AS Total_Girls'),
        DB::raw('Geographies.name AS District')
    )
    ->get();

基于Eloquent模型的简化方式(若定义了模型关联)

假设你已经在Institute模型中定义了与Enrollment的关联:

// Institute.php
public function enrollments()
{
    return $this->hasMany(Enrollment::class, 'form_id');
}

则可以用withSum直接统计每个机构的男女数,再按地区汇总:

$dist_total_gender = Institute::query()
    ->withSum('enrollments', 'total_boys')
    ->withSum('enrollments', 'total_girls')
    ->join('Geographies', 'institutes.district', '=', 'Geographies.id')
    ->groupBy('institutes.district', 'Geographies.name')
    ->select(
        DB::raw('SUM(enrollments_total_boys_sum) AS Total_Boys'),
        DB::raw('SUM(enrollments_total_girls_sum) AS Total_Girls'),
        DB::raw('Geographies.name AS District')
    )
    ->get();

核心逻辑说明

  1. 先对enrollements按form_id分组,统计每个机构的男女总数,避免一对多join产生的重复行。
  2. 再将统计结果与institutes、Geographies关联,最后按地区分组求和,得到准确的区域男女总数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 09:25:23