PHP如何按数组值分组 实现同月份盈利数据的重复项合并累加
原有代码问题定位
- 未做月份维度的分组逻辑:每处理一条商品销售记录就直接生成一个结果条目推入数组,自然产生大量同月份重复项
- 全局累计变量未做月份隔离:原代码中的
$netProfit、$maxProfit是跨所有月份持续累加的,统计数值本身就不符合单月独立核算的要求 - 缺少边界判断:如果销售产品不属于三个预设规格,
$price、$maxPrice变量不会被初始化,会触发PHP未定义变量警告
按月分组累加的实现方案
核心思路:以月份名作为关联数组的键做分组,每条销售记录计算出的单条利润直接累加到对应月份的分组下,最后将关联数组转成索引数组即可得到目标格式。
修改后的完整函数代码
function getMonthlyIncomeOfSellerById($sellerId) { $data = array(); $query = "SELECT date_format(created_at,'%M'), product_id,sell_discount,SUM(sell_quantity) FROM sellers_sells WHERE seller_id=? AND YEAR(created_at) = YEAR(CURRENT_DATE()) GROUP BY date_format(created_at,'%M'),seller_id,product_id ORDER BY created_at"; $stmt = $this->con->prepare($query); $stmt->bind_param('s',$sellerId); $stmt->execute(); $stmt->bind_result($monthName,$productId,$sellDiscount,$sellQuantity); while ($stmt->fetch()) { $d['monthName'] = $monthName; $d['productId'] = $productId; $d['sellDiscount'] = $sellDiscount; $d['sellQuantity'] = $sellQuantity; array_push($data, $d); } $stmt->close(); // 初始化分组关联数组,以月份名作为键存储分组数据 $monthlyGroups = []; foreach ($data as $dt) { $product = $this->getProductById($dt['productId']); $product['productPrice'] = ($product['productPrice']/100)*$dt['sellDiscount']; // 给单条利润设置默认值,避免未定义变量警告 $price = 0; $maxPrice = 0; if ($product['productName']==='PRODUCT NAME' && $product['productBrand']==='PRODUCT BRAND' && $product['productSize']==='50ML') { $maxPrice = $product['productPrice'] * $dt['sellQuantity']; $price = ($product['productPrice'] - 10) * $dt['sellQuantity']; } else if ($product['productName']==='PRODUCT NAME' && $product['productBrand']==='PRODUCT BRAND' && $product['productSize']==='100ML') { $maxPrice = $product['productPrice'] * $dt['sellQuantity']; $price = ($product['productPrice'] - 15) * $dt['sellQuantity']; } else if ($product['productName']==='PRODUCT NAME' && $product['productBrand']==='PRODUCT BRAND' && $product['productSize']==='200ML') { $maxPrice = $product['productPrice'] * $dt['sellQuantity']; $price = ($product['productPrice'] - 30) * $dt['sellQuantity']; } // 按月份累加到对应分组 $currentMonth = $dt['monthName']; if (!isset($monthlyGroups[$currentMonth])) { // 首次遇到该月份,初始化分组条目 $monthlyGroups[$currentMonth] = [ 'monthName' => $currentMonth, 'netProfit' => 0, 'maxProfit' => 0 ]; } $monthlyGroups[$currentMonth]['netProfit'] += $price; $monthlyGroups[$currentMonth]['maxProfit'] += $maxPrice; } // 关联数组转索引数组,得到最终格式的结果 $ddd = array_values($monthlyGroups); print_r($ddd); }
注意:原代码输出的同月份条目的
netProfit、maxProfit是跨月累计的数值,本身存在计算逻辑偏差。修改后的代码会独立统计每个月的真实利润总和,不会出现跨月叠加的问题,最终输出的数值符合单月独立核算的要求。
可选优化:按自然月份顺序排序
如果需要严格按照1-12月的自然顺序排列结果(而非按数据出现顺序),可以在最终输出前加入排序逻辑:
// 定义月份自然顺序映射 $monthOrder = [ 'January' => 1, 'February' => 2, 'March' => 3, 'April' => 4, 'May' => 5, 'June' => 6, 'July' => 7, 'August' => 8, 'September' => 9, 'October' => 10, 'November' => 11, 'December' => 12 ]; // 按自然月份排序 usort($ddd, function($a, $b) use ($monthOrder) { return $monthOrder[$a['monthName']] <=> $monthOrder[$b['monthName']]; });
内容的提问来源于stack exchange,提问作者user14236118
相关产品推荐
相关产品推荐

