Laravel多个withCount在同一关系上

Posted

技术标签:

【中文标题】Laravel多个withCount在同一关系上【英文标题】:Laravel multiple withCount on the same relationship 【发布时间】:2017-06-18 13:01:42 【问题描述】:

我需要计算两个不同条件的结果,来自同一个关系,但它以相同的名称返回。

Model::where('types_id', $specialism_id)
        ->withCount(['requests' => function ($query) 
            $query->where('type', 1);
        ])
        ->withCount(['requests' => function ($query) 
            $query->where('type', 2);
        ])

我可以使用$model->requests_count 访问withCount,但因为它查询的是相同的关系,所以它似乎覆盖了它:

select count(*) 
    from `requests` where `requests`.`id` = `model`.`id` 
    and `type` = '1') as `requests_count`, 
(select count(*) from `requests` where `requests`.`id` = `model`.`id` 
    and `type` = '2') as `requests_count`

如何为多个withCount指定名称?

【问题讨论】:

【参考方案1】:

你现在可以这样做了

Model::where('types_id', $specialism_id)
    ->withCount(['requests as requests_1' => function ($query) 
        $query->where('type', 1);
    , 'requests as requests_2' => function ($query) 
        $query->where('type', 2);
    ])

【讨论】:

工作就像一个魅力!为什么这些东西在文档中没有,你从哪里知道它会以这种方式工作? 这个我记不太清了,但是您可以查看下划线的类,了解哪些方法可用以及如何实现,这有助于您以最有效的方式编写内容。 【参考方案2】:

选项 1

创建两个不同的关系:

public function relationship1()

    return $this->hasMany('App\Model')->where('type', 1);


public function relationship2()

    return $this->hasMany('App\Model')->where('type', 2);

并使用它们:

Model::where('types_id', $specialism_id)->withCount(['relationship1', 'relationship2'])

选项 2

创建withCount() 类似的方法,该方法将使用自定义名称构建属性:

public function withCountCustom($relations, $customName)

    if (is_null($this->query->columns)) 
        $this->query->select([$this->query->from.'.*']);
    
    $relations = is_array($relations) ? $relations : func_get_args();

    foreach ($this->parseWithRelations($relations) as $name => $constraints) 
        $segments = explode(' ', $name);
        unset($alias);
        if (count($segments) == 3 && Str::lower($segments[1]) == 'as') 
            list($name, $alias) = [$segments[0], $segments[2]];
        
        $relation = $this->getHasRelationQuery($name);
        $query = $relation->getRelationCountQuery(
            $relation->getRelated()->newQuery(), $this
        );
        $query->callScope($constraints);
        $query->mergeModelDefinedRelationConstraints($relation->getQuery());
        $column = $customName; <---- Here you're overriding the property name.
        $this->selectSub($query->toBase(), $column);
    
    return $this;

并使用它:

Model::where('types_id', $specialism_id)
    ->withCountCustom(['requests' => function ($query) 
        $query->where('type', 1);
    ], 'typeOne')
    ->withCountCustom(['requests' => function ($query) 
        $query->where('type', 2);
    ], 'typeTwo')

【讨论】:

以上是关于Laravel多个withCount在同一关系上的主要内容,如果未能解决你的问题,请参考以下文章

在 Laravel 的 withCount() 方法中使用 DISTINCT

groupBy withCount 闭包(Laravel 5.3.26)

Laravel 在 withCount 方法上使用 where 子句

Laravel 雄辩用 whereHas 或其他限制 withCount

laravel5.3统计 withCount()方法的使用

Laravel - 具有关系条件