如何按月统计出销量最高的产品及对应总收益?
按月统计销量最高产品并展示销量及总收益的实现方法
我希望按月统计并展示销量最高的产品,同时显示其销量及总收益,但不清楚具体实现方法。以下是我目前尝试的代码:
public function viewSales(){ $data = sales::select( [sales::raw("SUM(product_fee) as product_fee, MONTHNAME(created_at) as month_name, MAX(bought) as bought"),'product'] )->whereYear('created_at', date("Y")) ->orderBy('created_at', 'asc') ->groupBy('month_name') ->get(); return view('admin.viewSales', compact('data')); }
数据库结构
| id | 产品 | 销量 | 产品单价 | 创建时间 |
|---|---|---|---|---|
| 1 | Dictionary | 1 | 200 | 2023-01-14 18:55:34 |
| 2 | Horror | 3 | 100 | 2023-01-15 17:55:34 |
| 3 | How to cook | 5 | 300 | 2023-01-16 11:55:34 |
期望展示效果
| 销量最高产品 | 销量 | 总收益 |
|---|---|---|
| How to cook | 5 | 600 |
问题分析
原代码存在几个核心问题:
- 仅按
month_name分组,未关联产品维度,无法统计单个产品的月度销量数据 MAX(bought)取的是单条记录的最大销量,不是该产品当月的总销量- 总收益计算错误,应该是销量×单价的总和,而非单纯的单价求和
修正后的实现代码
public function viewSales() { // 统计每个产品每月的总销量、总收益 $monthlyProductSales = \App\Models\Sales::select( 'product', \DB::raw('MONTHNAME(created_at) as month_name'), \DB::raw('SUM(bought) as total_sold'), \DB::raw('SUM(bought * product_fee) as total_earning') ) ->whereYear('created_at', date("Y")) ->groupBy('month_name', 'product') ->orderBy('month_name', 'asc') ->get(); // 按月份筛选出当月销量最高的产品 $data = $monthlyProductSales->groupBy('month_name')->map(function ($products) { return $products->sortByDesc('total_sold')->first(); }); return view('admin.viewSales', compact('data')); }
代码逻辑说明
- 分组统计:先按「月份+产品」分组,计算每个产品当月的总销量(
SUM(bought))和总收益(SUM(bought * product_fee)) - 筛选Top1:用集合的
groupBy按月份聚合数据,再对每个月的产品按销量降序排序,取第一条即为当月销量最高的产品 - 视图传递:最终
$data是包含各月Top产品数据的集合,可直接在视图中遍历展示
视图展示示例(Blade)
<table> <thead> <tr> <th>月份</th> <th>销量最高产品</th> <th>总销量</th> <th>总收益</th> </tr> </thead> <tbody> @foreach($data as $month => $product) <tr> <td>{{ $month }}</td> <td>{{ $product->product }}</td> <td>{{ $product->total_sold }}</td> <td>{{ $product->total_earning }}</td> </tr> @endforeach </tbody> </table>
内容的提问来源于stack exchange,提问作者HalpPlas
相关产品推荐
相关产品推荐

