Laravel中按周分组交易数据并在Blade展示的实现求助
解决方案
一、优化控制器逻辑(推荐数据库层面分组,性能更优)
原代码先查询全量数据再做集合分组,数据量大时效率低下,建议直接在SQL层面完成分组统计,同时加入年份避免跨年周号重复:
use Illuminate\Support\Facades\DB; $transact = Transaction::select( DB::raw('WEEK(created_at) as week_number'), DB::raw('YEAR(created_at) as year'), DB::raw('SUM(amount) as total_amount'), DB::raw('SUM(profit) as total_profit'), DB::raw('COUNT(*) as total_transactions'), // 按具体状态枚举统计数量,可根据实际status值调整 DB::raw('COUNT(CASE WHEN status = "success" THEN 1 END) as success_count'), DB::raw('COUNT(CASE WHEN status = "failed" THEN 1 END) as failed_count') ) ->groupBy('year', 'week_number') ->orderBy('year', 'desc') ->orderBy('week_number', 'desc') ->get();
如果坚持用集合分组(仅适合小数据量场景),可在集合上计算统计值:
$transact = Transaction::select('amount', 'profit', 'status', 'created_at') ->get() ->groupBy(function($row){ return $row->created_at->format('Y-W'); // 年份+周号作为分组键 }) ->map(function($group) { return [ 'total_amount' => $group->sum('amount'), 'total_profit' => $group->sum('profit'), 'total_transactions' => $group->count(), 'status_counts' => $group->countBy('status') // 按status统计数量 ]; });
二、完善Blade视图代码
场景1:使用数据库分组结果
<tbody> @foreach ($transact as $item) <tr> <!-- 显示年份+周数,格式如「2024-第32周」 --> <td>{{ $item->year }}-第{{ $item->week_number }}周</td> <!-- 总交易笔数 --> <td>{{ $item->total_transactions }}</td> <!-- 总金额(格式化保留两位小数) --> <td>{{ number_format($item->total_amount, 2) }}</td> <!-- 总利润(格式化保留两位小数) --> <td>{{ number_format($item->total_profit, 2) }}</td> <!-- 状态统计 --> <td>成功:{{ $item->success_count ?? 0 }} | 失败:{{ $item->failed_count ?? 0 }}</td> </tr> @endforeach </tbody>
场景2:使用集合分组结果
<tbody> @foreach ($transact as $weekKey => $data) <tr> <!-- 解析分组键中的年份和周数 --> <td> @php [$year, $week] = explode('-', $weekKey); @endphp {{ $year }}-第{{ $week }}周 </td> <!-- 总交易笔数 --> <td>{{ $data['total_transactions'] }}</td> <!-- 总金额 --> <td>{{ number_format($data['total_amount'], 2) }}</td> <!-- 总利润 --> <td>{{ number_format($data['total_profit'], 2) }}</td> <!-- 遍历所有状态的统计数量 --> <td> @foreach ($data['status_counts'] as $status => $count) {{ $status }}:{{ $count }}@if(!$loop->last) | @endif @endforeach </td> </tr> @endforeach </tbody>
关键提示
- 必须加入年份分组,否则跨年的相同周号(如每年第52周)会被错误合并。
- 数据库层面分组的性能远高于集合分组,优先使用第一种方案。
number_format用于格式化金额/利润,提升页面可读性,可根据需求调整小数位数。
内容的提问来源于stack exchange,提问作者Tracy
相关产品推荐
相关产品推荐

