如何在 Laravel 中通过 JOIN 和聚合函数统计每个商品的总入库数量

如何在 Laravel 中通过 JOIN 和聚合函数统计每个商品的总入库数量

本文介绍如何使用 laravel 的 query builder 对多表关联数据进行分组求和,解决因缺少 group by 导致重复行、无法汇总的问题,并给出正确实现与关键注意事项。

在实际开发中,常需基于主表(如 products)和关联表(如 ins 入库记录)统计每个商品的累计数量。你当前的查询虽然完成了表连接,但未进行分组(GROUP BY)和聚合(SUM()),导致每条入库记录单独返回一行,且 SUM() 在无分组时会对全表求和并复制到每一行——这正是你看到大量重复商品名和 null/零散数值的根本原因。

✅ 正确做法是:显式分组 + 聚合 + 选择非聚合字段需兼容 SQL 标准。以下是修正后的 Laravel 查询代码:

public function index()
{
    $productsWithTotal = DB::table('products')
        ->join('ins', 'products.id', '=', 'ins.products_id')
        ->select('products.name', DB::raw('SUM(ins.amount) as total_amount'))
        ->groupBy('products.id', 'products.name') // ✅ 必须按主键和 SELECT 中的非聚合字段分组
        ->get();

    return response()->json($productsWithTotal);
}

? 关键说明:

  • SUM(ins.amount) 计算每个商品所有入库记录的金额总和;
  • GROUP BY products.id, products.name 是必需的:Laravel 使用 MySQL 严格模式时,若 SELECT 包含非聚合字段(如 name),必须将其纳入 GROUP BY,否则会报错或结果不可靠;
  • 移除了原查询中多余的 ins.amount 字段——它属于明细数据,与汇总目标冲突;
  • 使用 total_amount 作为别名更语义化,避免与原始字段混淆。

⚠️ 注意事项:

知了追踪

知了追踪

AI智能信息助手,智能追踪你的兴趣资讯

下载

  • 若某商品在 ins 表中无任何记录,该商品将不会出现在结果中(因使用 INNER JOIN)。如需包含零库存商品,应改用 LEFT JOIN 并配合 COALESCE(SUM(ins.amount), 0);
  • 确保数据库字段类型支持数值运算(如 amount 应为 INT 或 DECIMAL,而非 VARCHAR);
  • 生产环境建议添加索引:ins(products_id) 可显著提升 JOIN 性能。

最终输出示例:

[
  {"name": "Aerobat", "total_amount": 124},
  {"name": "god of war", "total_amount": 30},
  {"name": "Rs537", "total_amount": 15}
]

这一结构清晰、可直接用于前端展示或进一步业务处理。

https://www.php.cn/faq/1987436.html

发表回复

Your email address will not be published. Required fields are marked *