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
相关产品推荐
相关产品推荐

