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
相关产品推荐
相关产品推荐

