本文介绍如何在 laravel 中通过关联查询,仅统计“已交付”(delivered)状态订单中的商品销量,并准确获取 top 3 畅销商品。
在构建电商或订单类后台仪表盘时,常需动态展示“最畅销商品”。但若直接对 order_details 表聚合销量(如 SUM(quantity)),会忽略订单实际履约状态——例如将已取消
、待发货或退款中的订单也计入销量,导致数据失真。要精准统计“已交付”商品的销量,关键在于跨表条件过滤 + 聚合分组。
Laravel 提供了优雅的解决方案:利用 whereHas() 方法,在聚合前先对关联的 orders 表施加状态约束。前提是已在 OrderDetails 模型中正确定义与 Order 的关联关系(如 belongsTo)。示例代码如下:
$top_sell_items = OrderDetails::with(['product', 'order']) // 推荐使用 'order'(单数)而非 'orders',更符合一对一语义
->whereHas('order', function ($query) {
$query->where('order_status', 'delivered'); // 注意字段名应为 'order_status'(与问题描述一致)
})
->select('product_id', DB::raw('SUM(quantity) as total_quantity'))
->groupBy('product_id')
->orderBy('total_quantity', 'desc')
->take(3)
->get();⚠️ 注意事项:
public function order()
{
return $this->belongsTo(Order::class, 'order_id');
}最终返回的 $top_sell_items 是 OrderDetails 集合,每个元素包含 product_id 和 total_quantity,并通过 product 关系可访问完整商品信息。此方案兼顾性能(单次 SQL 查询)、可读性与 Laravel 最佳实践。