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
相关产品推荐
相关产品推荐

