Laravel сгруппировать по иерархии моделей - PullRequest
0 голосов
/ 14 января 2020

Я искал это около двух дней на сайте, но не смог найти похожий пример. Я пытаюсь закодировать эквивалент этой 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 .

Спасибо заранее!

1 Ответ

0 голосов
/ 16 января 2020

Я не на 100% понимаю синтаксис Oracle, но похоже, что соединяет со мной.

Я бы "перевел" его в построитель запросов Laravel как:

DB::table('pers_data')
 ->join('misth_master', 'pers_data.per_emploeeno', '=', 'misth_master.emp_no')
 ->join('misth_detail', 'misth_master.misaa', '=', 'misth_detail.misaa')
 ->where('pers_data.per_emploeeno', '=', '04004')
 ->where('misth_master.year', '=', '2019')
 ->select(DB::raw('SUM(misth_detail.poso1) as total'))
 ->groupBy('misth_detail.code', 'misth_detail.grp', 'misth_detail.cname')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...