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

Laravel中如何按project_code分组计算并拆分各项目总额

按Project Code分组计算总额的解决方案

你现在需要按project_code分组计算每个项目的总额,而不是只算所有项目的总和对吧?这里有两种实用的方案,咱们一步步来看:

方案一:数据库层面直接分组计算(推荐)

这种方式让数据库来处理分组和聚合计算,效率更高,尤其是数据量较大的时候。我们可以修改查询构建器,使用groupBy和聚合函数来直接得到分组后的总额:

public function show($id) { 
    $Days = DB::table('payroll_monthly_attn_project')
        ->where('payroll_monthly_id',$id)
        ->where('assign','PAINTING') 
        ->select('wrk_id','project_code','days'); 

    $projectTotals = DB::table('payroll_monthly_payable_details')
        ->where('payroll_monthly_id', $id) 
        ->leftjoinSub($Days,'days',function($join){ 
            $join->on('payroll_monthly_payable_details.wrk_id','=','days.wrk_id'); 
        })
        // 计算单条记录的实际金额:(日薪*天数) - 迟到扣除 - 加班扣除 - 旷工扣除
        ->selectRaw('days.project_code, SUM((payroll_monthly_payable_details.daily_rate * days.days) - payroll_monthly_payable_details.absent - payroll_monthly_payable_details.late - payroll_monthly_payable_details.ut) as total')
        ->whereNotNull('days.project_code') // 过滤掉没有匹配到项目的记录(按需选择)
        ->groupBy('days.project_code')
        ->get(); 

    // 转成你期望的键值对格式
    $result = $projectTotals->mapWithKeys(function ($item) {
        return [$item->project_code => [
            'project_code' => $item->project_code,
            'total' => round($item->total, 2) // 保留两位小数让结果更规范
        ]];
    });

    return $result;
}

这个查询会直接返回符合预期的分组结果,示例输出:

{
  "CMUN": {"project_code": "CMUN", "total": 112.19},
  "N2": {"project_code": "N2", "total": 4773.19}
}

方案二:PHP层面循环分组计算

如果你想基于原来的查询结果在代码里处理,可以用数组来分组累加:

public function show($id) { 
    $Days = DB::table('payroll_monthly_attn_project')
        ->where('payroll_monthly_id',$id)
        ->where('assign','PAINTING') 
        ->select('payroll_monthly_attn_project.wrk_id','payroll_monthly_attn_project.project_code','payroll_monthly_attn_project.days'); 
    $Monthly_details = DB::table('payroll_monthly_payable_details')
        ->where('payroll_monthly_payable_details.payroll_monthly_id', $id) 
        ->select('payroll_monthly_payable_details.daily_rate','payroll_monthly_payable_details.late','payroll_monthly_payable_details.ut','payroll_monthly_payable_details.absent','days.*') 
        ->leftjoinSub($Days,'days',function($join){ 
            $join->on('payroll_monthly_payable_details.wrk_id','=','days.wrk_id'); 
        }) 
        ->get(); 

    $projectTotals = [];
    foreach($Monthly_details as $item){
        // 跳过没有项目代码的记录(如果存在的话)
        if(empty($item->project_code)) continue;
        
        // 计算当前记录的实际金额
        $itemTotal = ($item->daily_rate * $item->days) - $item->absent - $item->late - $item->ut;
        
        // 按项目代码分组累加
        if(isset($projectTotals[$item->project_code])){
            $projectTotals[$item->project_code]['total'] += $itemTotal;
        } else {
            $projectTotals[$item->project_code] = [
                'project_code' => $item->project_code,
                'total' => $itemTotal
            ];
        }
    }

    // 统一保留两位小数
    foreach($projectTotals as &$project){
        $project['total'] = round($project['total'], 2);
    }

    return $projectTotals;
}

运行这段代码后,就能得到你想要的分组统计结果啦。


内容的提问来源于stack exchange,提问作者Not a Pro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 19:17:52