Laravel Blade如何展示关联查询分组后的集合数据至HTML表格
在Laravel Blade中展示分组后的Join查询结果
我来帮你一步步实现这个需求,分两种常见场景讲解,你可以根据自己的表结构和需求灵活选择:
场景1:使用DB门面手动Join并分组
如果你的查询需要自定义Join逻辑,或者还没定义Eloquent模型关联,可以用这种方式:
第一步:控制器中编写查询逻辑
假设你有users和orders两张表,通过user_id关联,我们先执行关联查询,再通过Collection的groupBy方法按用户ID分组,把同一用户的数据归集到一个集合里:
public function showUserOrders() { // 执行Join查询,按需选择需要展示的字段 $userOrders = DB::table('users') ->join('orders', 'users.id', '=', 'orders.user_id') ->select( 'users.id as user_id', 'users.name as user_name', 'orders.id as order_id', 'orders.total_amount', 'orders.created_at' ) ->get() // 按user_id分组,得到每个用户对应的订单集合 ->groupBy('user_id'); return view('user-orders', compact('userOrders')); }
第二步:Blade视图中渲染表格
我们可以用嵌套表格来展示每个用户的订单详情,结构清晰直观:
<table class="table table-bordered"> <thead> <tr> <th>用户ID</th> <th>用户名</th> <th>订单列表</th> </tr> </thead> <tbody> @foreach($userOrders as $userId => $orders) <tr> <td>{{ $userId }}</td> <td>{{ $orders->first()->user_name }}</td> <td> <!-- 嵌套表格展示当前用户的所有订单 --> <table class="table table-sm table-striped"> <thead> <tr> <th>订单ID</th> <th>订单金额</th> <th>创建时间</th> </tr> </thead> <tbody> @foreach($orders as $order) <tr> <td>{{ $order->order_id }}</td> <td>{{ $order->total_amount }}</td> <td>{{ $order->created_at->format('Y-m-d H:i') }}</td> </tr> @endforeach </tbody> </table> </td> </tr> @endforeach </tbody> </table>
场景2:使用Eloquent关联(更优雅高效)
如果已经定义了Eloquent模型关联,强烈推荐这种方式,不仅代码更简洁,还能避免N+1查询的性能问题:
第一步:定义模型关联
在User模型中定义与Order的一对多关联:
namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\HasMany; class User extends Model { // 一个用户拥有多个订单 public function orders(): HasMany { return $this->hasMany(Order::class); } }
第二步:控制器中预加载关联数据
用with方法预加载订单数据,一次性获取所有用户和对应的订单,避免重复查询数据库:
public function showUserOrders() { // 预加载orders关联,高效获取所有用户及订单 $users = User::with('orders')->get(); return view('user-orders', compact('users')); }
第三步:Blade视图中渲染表格
这种方式的视图逻辑更清晰,因为每个用户对象已经自带了对应的订单集合:
<table class="table table-bordered"> <thead> <tr> <th>用户ID</th> <th>用户名</th> <th>订单列表</th> </tr> </thead> <tbody> @foreach($users as $user) <tr> <td>{{ $user->id }}</td> <td>{{ $user->name }}</td> <td> <table class="table table-sm table-striped"> <thead> <tr> <th>订单ID</th> <th>订单金额</th> <th>创建时间</th> </tr> </thead> <tbody> @if($user->orders->isNotEmpty()) @foreach($user->orders as $order) <tr> <td>{{ $order->id }}</td> <td>{{ $order->total_amount }}</td> <td>{{ $order->created_at->format('Y-m-d H:i') }}</td> </tr> @endforeach @else <tr> <td colspan="3" class="text-center text-muted">该用户暂无订单</td> </tr> @endif </tbody> </table> </td> </tr> @endforeach </tbody> </table>
关键注意点
- 如果你用数据库层面的
groupBy(不是Collection的groupBy),需要确保选择的字段要么在groupBy中,要么是聚合函数(比如COUNT、SUM),否则可能触发MySQL严格模式报错。 - 优先选择Eloquent关联的方式,代码更易维护,预加载还能大幅提升查询性能。
内容的提问来源于stack exchange,提问作者MJ DEV
相关产品推荐
相关产品推荐

