Laravel 5.5:如何获取指定店铺的销量Top5库存商品?
获取指定店铺销量Top5库存商品的最优实现(Laravel 5.5)
嘿,针对你在Laravel 5.5里要获取指定店铺销量Top5库存商品的需求,我给你整理了最优的实现方案——直接基于数据库层面的聚合查询,避免把大量数据拉到内存后再计算,性能拉满:
最优实现方案(数据库端聚合)
我们可以通过Shop模型的关联直接关联order_items表,统计每个库存商品的总销量,然后排序取前5。这种方式只需要一次数据库查询,效率最高:
use Illuminate\Support\Facades\DB; // 替换成你要查询的指定店铺ID $targetShopId = 1; $topSalesInventories = Shop::findOrFail($targetShopId) ->inventories() // 选择库存表的所有字段,同时统计总销量 ->select('inventories.*', DB::raw('SUM(order_items.quantity) as total_sales')) // 关联订单商品表,匹配库存ID ->join('order_items', 'inventories.id', '=', 'order_items.inventory_id') // 按库存ID分组,确保每个库存的销量被正确汇总 ->groupBy('inventories.id') // 按总销量倒序排列 ->orderBy('total_sales', 'desc') // 取Top5 ->take(5) ->get();
为什么这是最优解?
- 性能最优:所有统计和排序都在数据库完成,只返回你需要的5条数据,不需要加载店铺的所有库存再做内存计算。
- 代码简洁:利用Laravel Eloquent的关联特性,语义清晰,容易维护。
备选方案(Eloquent关联统计)
如果你更倾向于用Eloquent的belongsToMany关联来实现,也可以用withCount自定义统计字段,适合对代码可读性要求更高的场景:
$topSalesInventories = Inventory::where('shop_id', $targetShopId) ->withCount([ 'orders as total_sales' => function ($query) { // 统计该库存关联的所有订单的商品数量总和 $query->select(DB::raw('SUM(order_items.quantity)')); } ]) ->orderByDesc('total_sales') ->take(5) ->get();
注意事项
- 数据库配置:如果你的MySQL开启了
ONLY_FULL_GROUP_BY模式,直接用inventories.*分组可能会报错。这种情况下,建议明确指定需要的字段(比如inventories.id,inventories.name等),而不是用通配符*。 - 索引优化:为了让查询更快,建议给以下字段添加索引:
inventories.shop_id:加快筛选指定店铺库存的速度order_items.inventory_id:加快关联库存和订单商品的速度
内容的提问来源于stack exchange,提问作者Munna Khan
相关产品推荐
相关产品推荐

