Кажется, что нет способа сделать на уровне запроса только метод with()
;
Вот исходный код о with
https://github.com/laravel/framework/blob/5.8/src/Illuminate/Database/Eloquent/Builder.php#L1087
, он вернет отношениеимена и их ограничения и поместите их в массив eagerLoad.
А вот исходный код о get
и eagerLoadRelations
методах https://github.com/laravel/framework/blob/5.8/src/Illuminate/Database/Eloquent/Builder.php#L498 https://github.com/laravel/framework/blob/5.8/src/Illuminate/Database/Eloquent/Builder.php#L531
, которые он будет использоватьhydrate()
метод для сопоставления их и изменения их в коллекции, поэтому я думаю, что вы не можете суммировать их из верхней коллекции в ее дочернюю коллекцию, если только вы не измените исходный код.
Однако
Вы можете сделать это по коллекции, это снова цикл без базы данных запросов:
$details->map(function($detail) {
$detail['sum'] = $detail->partialfiles()->sum('partial_amount');
return $detail;
})
или
вы можете использовать join
самостоятельно, но это будет немного уродливо.
Плохой пример (Это будет запрос в базу данных несколько раз):
# this will take more querys times.
$details = File::join('partialfiles', 'partialfiles.file_id', '=', 'file.id')
->where('partialfiles.partial_date', '>=', $startdate)
->where('partialfiles.partial_date', '<=', $enddate)
->selectRaw('file.*', 'SUM(partialfiles.partial_amount) AS amount')
->groupBy('file.id')->get();
$details->map(function($detail)
{
return Partialfile::find($detail.id)->get();
});
Вот более быстрый, он займет всего один раз;
, и он вернеткаждая запись, включая частичные файлы, ее файл и сумму его суммы;
может быть, вам нужно изменить его в вашей структуре:
$details = File::join('partialfiles', 'partialfiles.file_id', '=', 'file.id')
->where('partialfiles.partial_date', '>=', $startdate)
->where('partialfiles.partial_date', '<=', $enddate)
->selectRaw('file.*', 'SUM(partialfiles.partial_amount) AS sum_amount')
->groupBy('file.id');
DB::table(DB::raw("({$details->toSql()}) AS fp"))
->mergeBindings($details->getQuery())
->join('partialfiles', 'partialfiles.file_id', '=', 'fp.id')
->get();
-- Here's the mysql code:
-- This only one query but you need to change the results to your structure:
select *
from (
select files.*, SUM(partialfiles.partial_amount) AS sum_amount
from files
join partialfiles on partialfiles.file_id = file.id
where partialfiles.startdate >= $now
and partialfiles.enddate <= $now
group by files.id
) as fp
join partialfiles on partialfiles.file_id = fp.id