You need to enable JavaScript to run this app. PHP如何按数组值分组 实现同月份盈利数据的重复项合并累加
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.01 22:45:03