Я искал это около двух дней на сайте, но не смог найти похожий пример. Я пытаюсь закодировать эквивалент этой Oracle команды в Eloquent:
select d.code, d.grp, d.cname, sum(d.poso1)
from pers_data e, misth_master m, misth_detail d
where e.per_emploeeno = m.emp_no
and m.misaa = d.misaa
and e.per_emploeeno = '04004'
and m.year = '2019'
group by d.code, d.grp, d.cname;
Она в основном объединяет 3 модели в иерархической форме (e - (has_many) -> m - (has_many) -> d ), накладывает ограничения на 1-е и 2-е и группирует / суммирует данные с 3-го. Результирующий набор выглядит следующим образом:
CODE GRP CNAME SUM(POSO1)
---- --- ----- ----------
153 1 cname1 0
2 0 cname2 3480
2 1 .. 1003,2
162 1 .. 250,8
5 .. 2464,67
30 4 .. 172,68
102 1 .. 949,08
105 1 .. 37,5
111 1 .. 25
0 0 .. 21600
11 1 cnamen 3976,26
В Laravel я объявил соответствующие модели (e = Сотрудник со связями с m = misthoi и d = details). После многих экспериментов я пришел к этим строкам кода, чтобы добиться этого: ( Обратите внимание, что модель Employee имеет глобальную область видимости и, следовательно, не требует ограничений в этом фрагменте кода, т.е. подразумевается'eper_emploeeno = '04004' )
$mdata_flat = Employee::with(['misthoi' => function ($query) {
$query->where('year', '2019');
}, 'misthoi.details'])->first()->misthoi->pluck('details')->flatten();
$mdata_grouped = $mdata_flat->groupBy(function ($item, $key) {
return $item['grp'].'.'.$item['code'];
})->map(function ($item) {
return [$item->max('cname'), $item->sum('poso1')];
})->toArray();
Это действительно работает, но мне кажется сложным, и я фанат простого читаемого кода. Я убежден, что есть отличный способ сделать это с Eloquent. Может ли он быть написан более простым способом?
Он может быть обобщен как:
Пусть A, B, C будут 3 иерархически связанными моделями (A-> B -> C). Я хочу сгруппировать данные по C только , основываясь на ограничениях на A и B .
Спасибо заранее!