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

Laravel Query Builder左连接丢失行:需保留无匹配行并填充空值

解决Laravel左连接后无匹配行被丢弃的问题

问题出在你对amenity_pricing_reviews表的过滤条件位置上——当前你把whereIn('apr.building_id', $data['building_ids'])和whereNull('apr.deleted_at')放在了全局的where子句里,这会让左连接的效果失效:当apr表没有匹配行时,apr.building_id和apr.deleted_at都是null,不满足这些where条件,所以整行被过滤掉了。

要保留无匹配的行,同时让apr相关字段为null,你需要把这两个条件移到左连接的on子句中,这样只会在关联apr表时筛选符合条件的行,不会影响主表的结果。

修改后的查询代码如下:

$results = DB::table('amenities as a') 
    ->leftJoin('amenity_values as av','av.amenity_id','=','a.id') 
    ->leftJoin('units_amenities_values as uav','uav.amenity_value_id','=','av.id') 
    ->leftJoin('units as u','uav.unit_id','=','u.id') 
    // 把apr的过滤条件移到on子句里
    ->leftJoin('amenity_pricing_reviews as apr', function($join) use ($data) {
        $join->on('apr.unit_id', '=', 'u.id')
             ->whereIn('apr.building_id', $data['building_ids'])
             ->whereNull('apr.deleted_at');
    })
    ->select('a.id as amenity_id','a.amenity_name','a.category_id', 'av.amenity_value','u.id as unit_id','u.unit_number','apr.dom','apr.building_id') 
    ->where('a.property_id', $data['property_id']) 
    ->whereNull('u.deleted_at') 
    ->whereNull('av.deleted_at') 
    ->whereNull('a.deleted_at') 
    ->orderBy('a.amenity_name','asc') 
    ->get() 
    ->groupBy(['category_id','unit_id']);

关键修改说明:

  • 将原本的普通leftJoin改为闭包形式的leftJoin,这样可以在on子句后追加额外的过滤条件
  • 把whereIn('apr.building_id', $data['building_ids'])和whereNull('apr.deleted_at')从全局where移到join的闭包内,确保只有符合条件的apr行才会被关联,没有匹配时则保留null值
  • 其他条件和后续的groupBy逻辑完全保留,确保结果结构和原有业务逻辑兼容

这样修改后,即使amenity_pricing_reviews表中没有匹配的行,主表的所有符合条件的行都会被保留,apr.dom和apr.building_id字段会自动填充为null,完全符合你的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 15:02:47