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

Laravel/SQL使用whereIn时如何同时获取单条明细与字段总和

问题根因

查询异常的核心问题是使用sum()聚合函数时没有配置正确的分组规则,MySQL非严格模式下会默认返回第一条匹配记录+全量结果的聚合值,自然无法返回所有店铺的需求明细。
另外原代码whereIn部分存在冗余逻辑:如果$request->rpId已经是数组格式,不需要再调用explode(",")处理,explode仅用于拆分逗号拼接的字符串参数。

方案1:窗口函数单次查询(推荐,适配MySQL 8.0及以上版本)

窗口函数可以在保留所有明细行的基础上,按商品维度计算跨店铺总需求量,单次查询即可拿到所需全部数据,性能最优。
Laravel实现代码:

$request->rpId = [3,4,8,9];
$purchaseOrders = DB::table('request_purchase_detail')
    ->join('request_purchase','request_purchase.id','=','request_purchase_detail.rpId')
    ->join('shop','shop.id','=','request_purchase.shopId')
    ->select(
        'request_purchase_detail.productId',
        'request_purchase_detail.productName',
        'shop.title',
        'request_purchase_detail.productQuantity as reqQty',
        'request_purchase_detail.rpId',
        DB::raw('sum(request_purchase_detail.productQuantity) OVER(PARTITION BY request_purchase_detail.productId) as totalProductQty')
    )
    ->whereIn('request_purchase_detail.rpId', $request->rpId)
    ->get();

返回字段说明:

  • reqQty:对应单店铺单个商品的单独需求量
  • totalProductQty:同一商品跨所有筛选店铺的总采购需求量
    所有符合筛选条件的店铺明细都会完整返回,不会出现丢记录的问题。

方案2:明细查询+PHP层汇总(兼容MySQL 5.x旧版本)

如果使用的MySQL版本低于8.0不支持窗口函数,可以先查询全量明细,再通过PHP逻辑按商品维度汇总总采购量,返回数据结构和方案1完全一致,普通采购单场景性能够用。
实现代码:

$request->rpId = [3,4,8,9];
// 第一步:查询全量店铺商品明细
$purchaseOrders = DB::table('request_purchase_detail')
    ->join('request_purchase','request_purchase.id','=','request_purchase_detail.rpId')
    ->join('shop','shop.id','=','request_purchase.shopId')
    ->select(
        'request_purchase_detail.productId',
        'request_purchase_detail.productName',
        'shop.title',
        'request_purchase_detail.productQuantity as reqQty',
        'request_purchase_detail.rpId'
    )
    ->whereIn('request_purchase_detail.rpId', $request->rpId)
    ->get();
// 第二步:按商品ID汇总总采购量
$totalQtyMap = $purchaseOrders->groupBy('productId')
    ->map(fn($items) => $items->sum('reqQty'));
// 第三步:给每条明细追加对应商品的总采购量
$purchaseOrders = $purchaseOrders->map(function($item) use ($totalQtyMap) {
    $item->totalProductQty = $totalQtyMap[$item->productId] ?? 0;
    return $item;
});

注意:不要尝试用普通GROUP BY实现需求,如果按所有非聚合字段分组,sum()计算的是单条分组记录的数量,无法拿到跨店铺的商品总采购量,不符合业务要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 06:51:20