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

如何对MySQL/Laravel两个查询结果的数量字段做减法并保留首查询字段?

实现方案

你可以根据实际业务场景选择以下两种方案实现需求:


方案1:SQL联查实现(推荐,性能更优)

直接在数据库层面完成关联和计算,避免多次查询和PHP层面的二次处理,数据量大时性能优势非常明显:

$products = DB::table('purchase_products')
    ->join('products', 'products.id', '=', 'purchase_products.product_id')
    // 左连接销售表,关联条件为匹配product_id和purchase_price
    ->leftJoin('sales_products', function ($join) {
        $join->on('sales_products.product_id', '=', 'purchase_products.product_id')
             ->on('sales_products.purchase_price', '=', 'purchase_products.purchase_price');
    })
    ->select(
        'products.product_name',
        'purchase_products.product_id',
        'purchase_products.purchase_price',
        DB::raw("SUM(purchase_products.quantity) as purchase_quantity"),
        // 无销售记录时默认销售数量为0,避免null导致计算错误
        DB::raw("IFNULL(SUM(sales_products.quantity), 0) as sales_quantity"),
        // 直接计算剩余库存数量
        DB::raw("SUM(purchase_products.quantity) - IFNULL(SUM(sales_products.quantity), 0) as remain_quantity")
    )
    ->groupBy('purchase_products.product_id', 'purchase_products.purchase_price', 'products.product_name')
    ->get();

查询结果会保留原采购查询的所有字段,同时直接返回扣除销售后的剩余数量。


方案2:基于现有查询的集合处理

如果需要保留原有两个独立查询的逻辑,可以用Laravel集合的方法做后续匹配计算:

  1. 首先修改原有两个查询,补充关联必须的product_id字段:
// 采购查询补充product_id字段
$purchase_products = DB::table('purchase_products')
    ->join('products','products.id','purchase_products.product_id')
    ->select('products.product_name','purchase_products.product_id','purchase_products.purchase_price',DB::raw("SUM(purchase_products.quantity) as purchase_quantity"))
    ->groupby('purchase_products.product_id','purchase_products.purchase_price', 'products.product_name')
    ->get();

// 销售查询补充product_id字段
$sales_products = DB::table('sales_products')
    ->select('sales_products.product_id','sales_products.purchase_price',DB::raw("SUM(sales_products.quantity) as sales_quantity"))
    ->groupby('sales_products.product_id','sales_products.purchase_price')
    ->get();
  1. 集合匹配计算剩余数量:
// 把销售集合转为键值对结构,方便快速匹配,键规则为 product_id:purchase_price
$salesMap = $sales_products->keyBy(function ($item) {
    return $item->product_id . ':' . $item->purchase_price;
});

// 遍历采购集合计算剩余数量
$result = $purchase_products->map(function ($purchase) use ($salesMap) {
    $key = $purchase->product_id . ':' . $purchase->purchase_price;
    // 无对应销售记录时销售数量默认为0
    $salesQuantity = $salesMap->get($key)?->sales_quantity ?? 0;
    // 原采购字段全部保留,新增剩余数量字段
    $purchase->remain_quantity = $purchase->purchase_quantity - $salesQuantity;
    return $purchase;
});

最终$result即为处理后的目标数据。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 20:51:01