我在Laravel 5.6中有许多嵌套的hasMany
关系。我正在寻找一种有效的方法来对关系中每个最外层节点的属性求和。
例如,每个都由hasMany
链接。
Country
- > States
- > Cities
- > Streets
- > Houses
如果我想对给定House->bedrooms
中的所有Country
求和,那么最有效的方法是什么?
目前我在内存中有一个渴望加载的Country
,如下所示:
$country->load('states.cities.streets.houses');
我试过了:
$country->states->cities->streets->houses->pluck('bedrooms')->sum()
但得到了:
此集合实例上不存在Property [cities]。
我可以通过各种关系的foreach
循环来做到这一点,但感觉必须在Laravel中内置一个更加代码有效的方法。我错过了什么?
由于
答案 0 :(得分:2)
如果结果很大,则不应在应用层中获得它们的总和。尝试使用SQL Sum函数。
如果你想以雄辩的方式做到这一点,这应该是你最好的解决方案:
Country::with(['states.cities.streets.houses' => function ($query) {
$query->select('bedrooms');
}])->sum('bedrooms');
如果不使用这样的数据库查询:
DB::table('countries')
->join('states', '..', '..')
->join('cities', '..', '..')
->join('streets', '..', '..')
->join('houses', '..', '..')
->selectRaw('SUM(bedrooms) as sum')
->pluck('sum')[0]
答案 1 :(得分:0)
您可以尝试以下代码。
Country::with(['states.cities.streets.houses' => function ($query) {
$query->select('bedrooms', '...');
}])->sum('bedrooms');
答案 2 :(得分:0)
我目前正在使用hasManyThrough
和State
上的City
解决此问题,然后:
$country->load('cities.houses');
echo $country->cities->sum(function ($city) {
return $city->houses->sum('bedrooms');
});
但它仍然感觉不好。任何更好的答案都非常赞赏。
答案 3 :(得分:0)
我创建了一个HasManyThrough
级的无限关系:Repository on GitHub
安装后,您可以像这样使用它:
class Country extends Model {
use \Staudenmeir\EloquentHasManyDeep\HasRelationships;
public function houses() {
return $this->hasManyDeep(House::class, [State::class, City::class, Street::class]);
}
}
$sum = $country->houses()->sum('bedrooms');