You need to enable JavaScript to run this app. Laravel多层嵌套关联场景下如何正确统计products表total字段总和
优惠活动
大模型
产品
解决方案
定价
更多

Laravel多层嵌套关联场景下如何正确统计products表total字段总和

你原代码的核心问题是在with()的关联约束闭包中直接调用了sum()方法,该方法会立即执行查询返回数值结果,而with()要求约束闭包必须返回查询构造器实例,因此整套嵌套预加载逻辑直接失效,最终仅执行了主表crop_types的全量查询。

最优解决方案(Laravel 8+ 推荐)

直接使用withSum()方法支持嵌套关联的点语法,一行代码即可完成每个crop_type对应所有产品total字段的总和统计:

$data = CropType::withSum('categories.varieties.products', 'total')->get();

执行后每个CropType实例会自动生成categories_varieties_products_sum_total属性,存储你需要的总和值。如果你要自定义统计字段别名,可以用withAggregate方法:

$data = CropType::withAggregate('categories.varieties.products', 'sum(total) as total_product_amount')->get();

最终可通过$item->total_product_amount访问统计结果。

兼容低版本Laravel方案

如果你的Laravel版本低于8不支持上述方法,可以用关联join的方式实现统计,性能同样高效:

$data = CropType::selectRaw('crop_types.*, SUM(products.total) as total_product_amount')
    ->leftJoin('categories', 'categories.crop_type_id', '=', 'crop_types.id')
    ->leftJoin('varieties', 'varieties.category_id', '=', 'categories.id')
    ->leftJoin('products', 'products.variety_id', '=', 'varieties.id')
    ->groupBy('crop_types.id')
    ->get();

注意:如果你的MySQL开启了ONLY_FULL_GROUP_BY模式,需要确保groupBy的字段和select中的非聚合字段完全对应,上述写法中crop_types.id为主键,因此select crop_types.*不会触发语法错误。

需要同时加载全量嵌套关联的方案

如果你不仅需要总和,还要加载所有层级的关联数据,可以按如下方式改写:

$data = CropType::with([
    'categories' => function($cq) {
        $cq->with(['varieties' => function($vq) {
            // 统计每个品种的产品总和
            $vq->withSum('products', 'total');
        }]);
    }
])
// 统计当前作物类型的总产品量
->withSum('categories.varieties.products', 'total')
->get();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 21:45:03