Laravel复杂查询:统计已审批采购订单中物料的总数量
Laravel复杂采购物料统计查询方案
这个需求需要同时处理直接采购物料和组合物料拆解后内嵌物料的数量统计,我会基于你给出的表结构,用Laravel Query Builder来实现这个逻辑:
核心逻辑拆解
我们需要分两部分计算数量,再合并求和:
- 直接采购的单个物料数量
- 组合物料中包含的单个物料数量(采购组合的数量 × 组合内物料配比)
完整查询代码
use Illuminate\Support\Facades\DB; // 1. 统计直接采购的物料数量 $directPurchases = DB::table('purchase_order_details as pod') // 关联已审批的采购订单 ->join('purchase_orders as po', 'pod.purchase_order_id', '=', 'po.id') // 关联库存表,确认是单个物料 ->join('inventories as inv', 'pod.inventory_item', '=', 'inv.name') ->where('po.status', 'approved') // 过滤已审批的订单,字段值请根据实际调整 ->select( 'inv.id as inventory_id', 'inv.name as inventory_name', DB::raw('SUM(pod.quantity) as total_quantity') ) ->groupBy('inv.id', 'inv.name'); // 2. 统计组合物料拆解后的内嵌物料数量 $compositePurchases = DB::table('purchase_order_details as pod') // 关联已审批的采购订单 ->join('purchase_orders as po', 'pod.purchase_order_id', '=', 'po.id') // 关联组合库存表,确认是组合物料 ->join('composite_inventories as ci', 'pod.inventory_item', '=', 'ci.name') // 关联组合-物料中间表,获取配比 ->join('composite_has_inventories as chi', 'ci.id', '=', 'chi.composite_inventory_id') // 关联库存表,定位到内嵌的单个物料 ->join('inventories as inv', 'chi.inventory_id', '=', 'inv.id') ->where('po.status', 'approved') ->select( 'inv.id as inventory_id', 'inv.name as inventory_name', // 计算:采购组合的数量 × 组合内该物料的配比数量 DB::raw('SUM(pod.quantity * chi.quantity) as total_quantity') ) ->groupBy('inv.id', 'inv.name'); // 3. 合并两部分数据,按物料汇总总数量 $finalStats = DB::table(DB::raw("({$directPurchases->toSql()} UNION ALL {$compositePurchases->toSql()}) as combined_data")) // 合并两个子查询的绑定参数,避免SQL注入 ->mergeBindings($directPurchases) ->mergeBindings($compositePurchases) ->select( 'inventory_id', 'inventory_name', DB::raw('SUM(total_quantity) as total_quantity') ) ->groupBy('inventory_id', 'inventory_name') ->get();
关键细节说明
- 表字段适配:请根据你的实际数据库结构调整字段名,比如采购订单的审批状态字段(
po.status)的取值、inventory_item如果存储的是ID而非名称,需要把关联条件改成ID匹配 - SQL注入防护:使用
mergeBindings方法合并子查询的参数,避免直接拼接SQL带来的安全风险 - 结果格式:最终
$finalStats会返回每个物料的ID、名称和总采购数量,比如你例子中的stest2会得到total_quantity = 11
可选优化:用Eloquent模型关联实现
如果你的项目中已经定义了对应的Eloquent模型,可以基于模型关联来重构这段代码,可读性会更好,但核心逻辑和上面的Query Builder是一致的。
内容的提问来源于stack exchange,提问作者Code Embassy
相关产品推荐
相关产品推荐

