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

Laravel Eloquent join查询如何筛选具备所有用户选中amenities的酒店

解决方案

原查询的逻辑是只要酒店匹配到任意一个选中的设施就会返回,要实现「匹配全部选中设施」,可以通过分组后统计匹配设施数量的方式实现,修改后的代码如下:

$builder = Hotels::query(); 
$builder->select('hotels.id', 'hotels.hotel_name'); // 修正原代码字段拼接笔误
$request_amenities = $request->amenities;

// 先判断是否有传入设施筛选条件,避免空数组报错
if (!empty($request_amenities)) {
    $amenity_count = count($request_amenities);
    $builder->join('amenities_hotels', function ($join) use($request_amenities) {
        // 修正原代码关联表名笔误:hotel.id 改为 hotels.id
        $join->on('amenities_hotels.hotel_id', '=', 'hotels.id')
            ->whereIn('amenities_hotels.amenities_id', $request_amenities);
    });
    // 按酒店分组,统计匹配到的设施数量等于选中的设施总数
    $builder->groupBy('hotels.id')
        ->havingRaw('COUNT(DISTINCT amenities_hotels.amenities_id) = ?', [$amenity_count]);
}

逻辑说明

  • 先通过whereIn过滤出所有和选中设施匹配的中间表关联记录,排除完全不相关的酒店
  • 按酒店ID分组后,每个酒店对应的关联记录数就等于它具备的选中设施的数量
  • 加DISTINCT是为了避免中间表存在重复关联记录时统计结果出错
  • 当统计的数量等于传入的选中设施总数时,就说明该酒店具备所有选中的设施

提示:如果你的数据库开启了严格模式,出现group by相关报错,把分组规则改为groupBy('hotels.id', 'hotels.hotel_name')即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 16:54:01