Laravel Eloquent查询中如何同时获取数据与amount字段总和
解决Laravel Eloquent查询中同时获取列表与总和的问题
你遇到的问题很典型——直接在查询中添加SUM()聚合函数会导致结果集被合并成单条记录,因为聚合函数默认会把所有匹配的行归为一个分组。下面给你几种高效的解决方案:
方案一:克隆查询单独计算总和(推荐)
这是性能最优的方式,通过克隆已构建好的查询条件来计算总和,同时保留原有的分页逻辑:
// 构建基础查询条件 $query = SalesPayment::with(['abc.xyz']) ->whereHas('abc.xyz', function ($query) use ($options) { $query->where('xyz_id', $options['xyz_id']); }) ->where([ 'key3' => key3(), 'payment_status' => PAYMENT_STATUS_SUCCESS ]) ->orderBy('created_at', 'desc'); // 克隆查询并计算符合条件的所有记录的amount总和 $totalSaleAmount = $query->clone()->sum('amount'); // 执行分页查询 $paginatedResults = $query->paginate(config('constants.PAGE_LIMIT')); // 将总和附加到分页结果中(可选,根据你的返回格式调整) $paginatedResults->append('total_sale_amount', $totalSaleAmount); // 或者返回包含总和与分页数据的数组 return [ 'data' => $paginatedResults->items(), 'total_sale_amount' => $totalSaleAmount, 'pagination' => [ 'current_page' => $paginatedResults->currentPage(), 'last_page' => $paginatedResults->lastPage(), 'per_page' => $paginatedResults->perPage(), 'total_records' => $paginatedResults->total() ] ];
为什么这个方案好用?
- 复用了已有的查询条件,避免重复写where/whereHas逻辑
- 只执行两次查询:一次分页、一次总和,性能开销极低
- 完美保留原有的分页功能,不会破坏原有业务逻辑
方案二:使用子查询在每条记录中携带总和(不推荐用于大数据量)
如果你希望总和直接出现在每条返回的记录中,可以用子查询实现,但要注意这种方式在数据量大时会有性能损耗(每条记录都会执行一次子查询):
$query = SalesPayment::with(['abc.xyz']) ->whereHas('abc.xyz', function ($query) use ($options) { $query->where('xyz_id', $options['xyz_id']); }) ->where([ 'key3' => key3(), 'payment_status' => PAYMENT_STATUS_SUCCESS ]) ->selectRaw(' *, (SELECT SUM(amount) FROM sales_payments sp WHERE sp.key3 = ? AND sp.payment_status = ? AND EXISTS ( SELECT 1 FROM abc a WHERE a.id = sp.abc_id AND EXISTS ( SELECT 1 FROM xyz x WHERE x.id = a.xyz_id AND x.id = ? ) )) AS total_sale_amount ', [key3(), PAYMENT_STATUS_SUCCESS, $options['xyz_id']]) ->orderBy('created_at', 'desc') ->paginate(config('constants.PAGE_LIMIT')); return $query;
为什么你的原方案会失败?
当你在select中添加SUM(amount)时,MySQL会将所有匹配的行视为一个分组(因为没有指定GROUP BY),所以最终只会返回一条包含总和的记录,自然丢失了原本的多条分页数据。
内容的提问来源于stack exchange,提问作者Radhe Shyam Sharma
相关产品推荐
相关产品推荐

