如果另一个连接为空,Laravel Eloquent 和 Mysql 连接一个表

Posted

技术标签:

【中文标题】如果另一个连接为空,Laravel Eloquent 和 Mysql 连接一个表【英文标题】:Laravel Eloquent and Mysql join a table IF another join is null 【发布时间】:2018-10-05 17:09:04 【问题描述】:

三个主表:

产品

广告商

地点

两个数据透视表:

广告商位置

products_locations

关系:

一个产品属于一个广告商,一个广告商有很多位置(可以将产品运送到的位置)

产品还可以拥有自己的一组位置,这些位置会覆盖广告客户的位置(某些产品有配送限制)

我需要做的是:

    选择所有产品

    检查 products_locations 表中的产品 ID 并加入它。

    如果不存在则加入广告商位置表

这可以在一个查询中使用 eloquent 完成吗?这是我的代码 - 与条件作斗争:

public function scopeWhereShippableToLocation($query)
    
        $location_id = session('location_id');

        $query->where(function ($q) use ($location_id) 
            $q->join('products_locations', 'products_locations.product_id', '=', 'products.id')
                ->where('products_locations.location_id', '=', $location_id);
        );

        $query->orWhere(function ($q) use ($location_id) 
            $q->join('advertisers_locations', 'advertisers_locations.advertiser_id', '=', 'products.advertiser_id')
                ->where('advertisers_locations.location_id', '=', $location_id);
        );


        //dd($q->toSql());

        return $query;
    

目前正在产生 mysql 错误:

    Column not found: 1054 Unknown column 'products_locations.location_id' in 'where clause' (SQL: select `products`.*, 

【问题讨论】:

【参考方案1】:

我想我有一个使用 eloquent 的解决方案,而不是查询生成器。您需要检查关系是否存在,如果不存在,则需要另一个查询。这可以使用以下方法完成:

public function scopeWhereShippableToLocation($query)
    
        $location_id = session('location_id');

        // WhereHas check to see if a relationship exists, IE: The pivot table
        // orWhereHas will be checked if the first where does not exist

        $query->whereHas('products_locations', function ($q) use ($location_id) 
            $q->where('location_id', $location_id);
        )->orWhereHas('advertisers_locations', function ($q) use ($location_id) 
            $q->where('location_id', $location_id);
        );

        return $query;
    

只要设置了 ProductsAdvertisersLocations 关系方法,这应该可以工作。

【讨论】:

谢谢!稍作修改,它就可以完美运行:->orWhereDoesntHave('locations')->whereHas('advertiser.locations') (如果找到第一个匹配项,只需忽略辅助查询)

以上是关于如果另一个连接为空,Laravel Eloquent 和 Mysql 连接一个表的主要内容,如果未能解决你的问题,请参考以下文章

Laravel Factory:如何使一个字段具有内容而另一个字段为空

Laravel 验证规则 - 要求字段显式为空,具体取决于另一个字段的值 (type_id)

Laravel 不保存一对多关系

如果它们在 Python 中不为空,则连接多个字符串

Laravel 验证中有时和可为空的区别

Laravel属于合并吗?