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

Laravel分组后求和报错:Call to a member function sum() on string

解决Laravel中GroupBy后求和触发的"Call to a member function sum() on string"错误

嘿,我一眼就看出你代码里的问题啦!你在groupBy的回调里犯了个逻辑错误——Carbon::parse($date->created_at)->format('W,M,Y')返回的是字符串类型的日期(比如"32,Aug,2024"),你居然直接在这个字符串上调用sum('price'),这不触发"Call to a member function sum() on string"错误才怪呢!

错误根源拆解

你的代码逻辑搞反了:groupBy的回调只需要返回分组的标识(键),而不是直接在回调里做求和操作。求和应该是分组完成后,对每个分组集合进行的操作。

解决方案1:集合层面分组求和(适合小数据量)

先把符合条件的数据查出来,再按格式化后的日期分组,最后对每个分组的price字段求和:

// 注意模型名要大写,Laravel规范是首字母大写的模型类
$invoices = Invoice::where('instructor_id', '=', $id)->get();

$groupedData = $invoices->groupBy(function($invoice) {
    // 这里只返回分组的键:格式化后的日期字符串
    return Carbon::parse($invoice->created_at)->format('W,M,Y');
})->map(function($group) {
    // 对每个分组里的所有记录,求和price字段
    return $group->sum('price');
});

这样$groupedData里就会是类似["32,Aug,2024" => 1500, "33,Aug,2024" => 2200]的键值对,键是格式化后的日期,值是对应分组的总价。

解决方案2:数据库层面分组求和(推荐,大数据量更高效)

如果你的数据量比较大,把所有数据拉到内存里再处理会很影响性能,直接让数据库帮你完成分组和求和操作更靠谱:

// MySQL版本:用DATE_FORMAT格式化日期,和Carbon的W,M,Y对应
$groupedData = Invoice::where('instructor_id', '=', $id)
    ->selectRaw('DATE_FORMAT(created_at, "%v,%b,%Y") as date_group, SUM(price) as total_price')
    ->groupBy('date_group')
    ->get();

// 如果你用的是PostgreSQL,把DATE_FORMAT换成TO_CHAR:
// ->selectRaw('TO_CHAR(created_at, \'WW,Mon,YYYY\') as date_group, SUM(price) as total_price')

这种方式下,数据库会直接返回分组后的结果集合,每个元素包含date_group(格式化后的日期)和total_price(对应分组的总价),性能比集合处理高很多。

额外注意点

  • 模型名要遵循Laravel规范:首字母大写(Invoice而非invoice),避免类找不到的错误;
  • 确保created_at字段是日期/时间类型,Carbon能正确解析;
  • 不同数据库的日期格式化函数有差异,比如MySQL用DATE_FORMAT,PostgreSQL用TO_CHAR,SQL Server用FORMAT,要根据你的数据库类型调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 14:42:31