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

Laravel中如何关联两张表并按主表ID分组?

解决酒店查询重复显示的问题

你遇到的核心问题是LEFT JOIN会把每个关联的人员和酒店拼成单独的记录,导致酒店随着关联人员的数量重复出现。这里给你两种实用的解决思路,优先推荐第一种,更贴合Laravel的最佳实践:

方法一:使用Eloquent关联(推荐)

这种方式更优雅,能直接把每个酒店对应的人员集合作为对象属性获取,还能避免N+1查询的性能问题。

1. 定义模型关联

先在Hotel模型里添加和People模型的关联关系:

// app/Models/Hotel.php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Hotel extends Model
{
    protected $table = 'hotels';

    // 声明一个酒店对应多个人员的关联
    public function people()
    {
        return $this->hasMany(People::class, 'hotel_id');
    }
}

2. 预加载关联数据

在控制器里用with()方法预加载人员数据,一次性完成酒店和对应人员的查询:

use App\Models\Hotel;

// ...

$hotels = Hotel::with('people')->get();
return view('hotels', ['hotels' => $hotels]);

3. 视图中嵌套遍历展示

现在每个$hotel对象都自带people属性,是该酒店下的所有人员集合,直接嵌套遍历就能避免酒店重复:

@foreach($hotels as $hotel)
    <div class="hotel-card">
        <h3>{{ $hotel->name }}</h3>
        <div class="staff-list">
            @if($hotel->people->isNotEmpty())
                <ul>
                    @foreach($hotel->people as $person)
                        <li>{{ $person->name }}</li>
                    @endforeach
                </ul>
            @else
                <p>该酒店暂无人员</p>
            @endif
        </div>
    </div>
@endforeach

方法二:使用原生查询分组(适合无模型场景)

如果你不想用Eloquent模型,也可以通过GROUP BY结合聚合函数把人员名字拼接起来,直接消除酒店重复:

修正并调整查询代码

注意:你原代码里的hotel.id是笔误,应该是hotels.id,先修正这个错误。然后用MySQL的GROUP_CONCAT函数把人员名字拼接成字符串:

$hotels = DB::table('hotels')
    ->select(
        'hotels.*',
        DB::raw('GROUP_CONCAT(people.name SEPARATOR ", ") as people_names')
    )
    ->leftjoin('people', 'people.hotel_id', '=', 'hotels.id')
    ->groupBy('hotels.id') 
    // 提示:如果MySQL开启了严格模式,需要把hotels的所有字段都加入GROUP BY,或者调整sql_mode关闭严格分组检查
    ->get();

return view('hotels', ['hotels' => $hotels]);

视图展示

直接输出拼接好的人员名字即可:

@foreach($hotels as $h)
    <div>
        <strong>{{ $h->name }}</strong>: {{ $h->people_names ?? '无人员' }}
    </div>
@endforeach

补充:如果用的是PostgreSQL,需要把GROUP_CONCAT换成STRING_AGG(people.name, ', '),不同数据库的字符串聚合函数略有差异。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:07:38