Laravel 中统计用户所属业务下缺货商品总数及总采购价

本文介绍如何在 laravel 中通过 eloquent 或查询构造器,统计指定用户所创建业务下的缺货商品(库存为 0)总数及其采购价总和。

在实际库存管理系统中,常需快速识别“缺货商品”(即 quantity_in_stock = 0)并汇总其采购成本,辅助采购决策或库存预警。结合你提供的 items 表结构,关键字段包括:price(采购单价)、quantity_in_stock、business_id(关联企业),且业务与用户通过 businesses 表关联(假设 users ↔ businesses 为一对多关系)。

⚠️ 注意:原答案中存在两处关键错误,需立即修正:表名拼写错误:'itmes' → 应为 'items';SQL 字符串拼接错误:sum('price') 中的单引号会导致 SQL 解析为字符串字面量,正确写法是 sum(price)(无引号)或使用 DB::raw('SUM(price)')。

✅ 推荐使用 Eloquent 关系链式查询,兼顾可读性、安全性和可维护性:

// 假设已定义模型:User → hasMany Business → hasMany Item
$user = auth()->user(); // 或通过参数获取指定用户

$totalOutOfStock = $user->businesses()
    ->withCount(['items as out_of_stock_count' => function ($query) {
        $query->where('quantity_in_stock', 0);
    }])
    ->withSum(['items as out_of_stock_total_price' => function ($query) {
        $query->where('quantity_in_stock', 0);
    }], 'price')
    ->get()
    ->map(function ($business) {
        return [
            'business_id' => $business->id,
            'out_of_stock_count' => $business->out_of_stock_count,
            'out_of_stock_total_price' => (float) $business->out_of_stock_total_price,
        ];
    });

// 若只需全局聚合(所有业务合计):
$summary = $user->businesses()
    ->join('items', 'businesses.id', '=', 'items.business_id')
    ->where('items.quantity_in_stock', 0)
    ->selectRaw('COUNT(*) as total_items, SUM(items.price) as total_price')
    ->first();

若偏好原始查询构造器(如需极致性能或复杂条件),请使用以下修正后代码

use Illuminate\Support\Facades\DB;

$result = DB::table('items') // ✅ 修正表名
    ->select(
        'business_id',
        DB::raw('COUNT(*) as total_number'),
        DB::raw('SUM(price) as total_price') // ✅ 移除单引号,确保列名解析
    )
    ->where('quantity_in_stock', 0)
    ->groupBy('business_id')
    ->get();

? 额外建议

  • 为提升查询性能,在 items(quantity_in_stock, business_id) 上添加复合索引:
    Schema::table('items', function (Blueprint $table) {
        $table->index(['quantity_in_stock', 'business_id']);
    });
  • 对于 price 和 selling_price 字段,推荐改用 decimal(10,2) 替代 float,避免浮点数精度问题(如 0.1 + 0.2 ≠ 0.3);
  • 在 API 响应中,建议对 total_price 显式格式化为两位小数:number_format($item->total_price, 2)。

通过上述方式,你不仅能准确获取每个业务的缺货统计,还可灵活扩展为按时间范围、品类等维度聚合,真正构建健壮的库存分析能力。