You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中如何实现按商品聚合的上月订单项销量金额统计报表

实现订单项按商品聚合的两种方案

方案一:直接查询聚合(性能最优,推荐)

你可以直接从中间表order_items关联查询,按商品id分组聚合,一步拿到汇总结果,不需要遍历所有订单再处理:

use App\Models\Item;
use Carbon\Carbon;

// 获取上月完整时间范围,避免跨年时仅按月份查询出现数据错误
$lastMonthStart = Carbon::now()->subMonth()->startOfMonth();
$lastMonthEnd = Carbon::now()->subMonth()->endOfMonth();

$itemSummaries = Item::query()
    ->selectRaw('items.name, sum(order_items.quantity) as total_quantity, sum(order_items.price * order_items.quantity) as total_price')
    ->join('order_items', 'items.id', '=', 'order_items.item_id')
    ->join('orders', 'order_items.order_id', '=', 'orders.id')
    ->whereBetween('orders.created_at', [$lastMonthStart, $lastMonthEnd])
    ->groupBy('items.id', 'items.name')
    ->get();

Blade 模板部分直接遍历汇总结果即可:

<table>
  <tr>
    <th>商品名称</th>
    <th>总数量</th>
    <th>总金额</th>
  </tr>
  @foreach($itemSummaries as $summary)
  <tr>
    <td>{{ $summary->name }}</td>
    <td>{{ $summary->total_quantity }}</td>
    <td>{{ $summary->total_price }}</td>
  </tr>
  @endforeach
</table>

方案二:基于现有订单集合处理

如果你需要保留原有的订单查询逻辑,也可以用 Laravel 集合的方法对已有结果做聚合:
控制器部分在原有查询后补充聚合逻辑:

use Carbon\Carbon;

$lastMonthStart = Carbon::now()->subMonth()->startOfMonth();
$lastMonthEnd = Carbon::now()->subMonth()->endOfMonth();

$orders = Order::with('items')
               ->whereBetween('created_at', [$lastMonthStart, $lastMonthEnd])
               ->get();

// 按商品维度聚合数据
$itemSummaries = collect();
$orders->pluck('items')->flatten()->each(function ($item) use ($itemSummaries) {
    if ($itemSummaries->has($item->id)) {
        $existItem = $itemSummaries->get($item->id);
        $existItem['total_quantity'] += $item->pivot->quantity;
        $existItem['total_price'] += $item->pivot->price * $item->pivot->quantity;
        $itemSummaries->put($item->id, $existItem);
    } else {
        $itemSummaries->put($item->id, [
            'name' => $item->name,
            'total_quantity' => $item->pivot->quantity,
            'total_price' => $item->pivot->price * $item->pivot->quantity
        ]);
    }
});

Blade 遍历逻辑和方案一完全一致即可。

注意:原查询仅用whereMonth筛选月份会出现跨年数据错误问题,比如今年1月查询上月会拿到往年所有12月的订单,建议替换为whereBetween限定完整的上月时间范围。

内容的提问来源于stack exchange,提问作者Prince

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 19:45:04