如何通过单条查询获取指定时间范围内销量最高的商品
可以通过单条查询实现需求,先分析你原有代码的问题:
with('order_products')是Laravel的关联预加载逻辑,仅会在主查询完成后再执行关联查询填充关联属性,不会将关联表纳入主查询的SQL统计逻辑,因此无法直接在主查询中统计关联表的字段计数- 没有使用
GROUP BY对商品维度分组,count()聚合函数无法正确统计每个商品的销量 whereBetween的时间参数顺序颠倒,需要把起始时间$request->from放在前,结束时间$request->to放在后- 排序默认是升序,要获取销量最高的商品需要设置为降序排序
正确实现代码:
// 获取指定时间范围内销量从高到低排序的商品列表 $topProducts = \App\Models\Product::select( 'products.id', 'products.title', \DB::raw('COUNT(order_products.product_id) as sales_volume') ) // 关联订单商品表 ->join('order_products', 'products.id', '=', 'order_products.product_id') // 关联订单表过滤已支付、时间范围条件 ->join('orders', 'order_products.order_id', '=', 'orders.id') ->where('orders.paid', 1) ->whereBetween('orders.created_at', [$request->from, $request->to]) // 按商品维度分组统计销量 ->groupBy('products.id', 'products.title') // 按销量降序排序 ->orderBy('sales_volume', 'desc') // 若只需要销量最高的单个商品,把get()换成first()即可 ->get();
如果你的MySQL开启了严格模式,上述写法中
GROUP BY指定的字段和SELECT里的非聚合字段完全对应,不会出现语法错误。如果需要额外返回商品的其他字段,只需在select和groupBy里同步添加对应字段即可。
内容的提问来源于stack exchange,提问作者JKSDS
相关产品推荐
相关产品推荐

