Laravel 获取一个查询以检查 QueryBuilder 是不是存在两个关系中的至少一个而不忽略其他过滤器

Posted

技术标签:

【中文标题】Laravel 获取一个查询以检查 QueryBuilder 是不是存在两个关系中的至少一个而不忽略其他过滤器【英文标题】:Laravel get a query to check if at least one of two relationships exist with QueryBuilder without ignoring other filtersLaravel 获取一个查询以检查 QueryBuilder 是否存在两个关系中的至少一个而不忽略其他过滤器 【发布时间】:2021-10-07 18:29:56 【问题描述】:

我有一个模型 Affiliate,它与活动和转移具有 hasMany() 关系

我现在正在过滤我的附属公司,并希望检索至少有 1 次活动或至少一次转移的附属公司(它可以有 0 次活动和 1 次转移并且将通过)。此外,我必须忽略给定的无效会员 ID 数组

这是我尝试过的

$affiliates = Affiliate::whereNotIn('id',$invalidIds);
        if ($params['sales'])
            $affiliates = $affiliates->whereHas('activities', static function (Builder $builder) use ($params) 
                $builder->where('status','>',0)
                        ->where('status','<',8)
                        ;  
            )->orWhereHas('transfers', static function (Builder $builder) use ($params) 
                $builder->where('status','>',0)
                        ->where('status','<',8)  
                        ;
            );
        
        $affiliates = $affiliates->get();

使用 whereHas 和 orWhereHas 应该可以工作,但我认为的问题是,在 orWhereHas() 中,它目前忽略了其他过滤器(在这种情况下,过滤器忽略了附属公司的 $invalidIds)所以我得到的附属公司至少有一项活动或一项转移,但我不会忽略无效的 ID

我做错了吗?还是有不同的方法来解决这个问题?

【问题讨论】:

【参考方案1】:

试试这个:

$affiliates = Affiliate::whereNotIn('id',$invalidIds);

if ($params['sales'])
  $affiliates = $affiliates->where(function($query)
    $query->whereHas('activities', function ($q1)
        $q1->where('status','>',0)->where('status','<',8);
    )
    ->orWhereHas('transfers',function ($q2)
        $q1->where('status','>',0)->where('status','<',8);
    );
  );

$affiliates = $affiliates->get();

【讨论】:

【参考方案2】:

我不完全确定,但我认为使用方法顺序会起作用。

        $affiliates = Affiliate::query();
    if ($params['sales']) 
        $affiliates = $affiliates->whereHas('activities', static function (Builder $builder) use ($params) 
            $builder->where('status', '>', 0)
                ->where('status', '<', 8);
        )->orWhereHas('transfers', static function (Builder $builder) use ($params) 
            $builder->where('status', '>', 0)
                ->where('status', '<', 8);
        );
    
    $affiliates = $affiliates->whereNotIn('id', $invalidIds)->get();

【讨论】:

以上是关于Laravel 获取一个查询以检查 QueryBuilder 是不是存在两个关系中的至少一个而不忽略其他过滤器的主要内容,如果未能解决你的问题,请参考以下文章

如何从两个不同的 Laravel 查询构建器中获取我的两个结果集以同时显示在同一页面上?

对 laravel 的查询以从“已填充”且不为空的 db 行中获取百分比

Laravel 集合查询

如何从 laravel 5.0 中的 Request 类中获取所有查询字符串

编写一个工具以编程方式检查 Netezza(纯数据)是不是存在偏差并获取查询计划

如何使用查询生成器向 created_at 字段插入值