Laravel eloquent построитель запросов - сумма с группой по отношению - PullRequest
0 голосов
/ 24 апреля 2019

Я ищу решение для построения запросов для следующего:

Таблица: тип_транспорта

| id | type_hash | description     | category |
|----|-----------|-----------------|----------|
| 1  | abcd      | sale price      | sale     |
| 2  | dbac      | sale tax        | sale     |
| 3  | agft      | sale shipping   | sale     |
| 4  | pgsk      | refund price    | refund   |
| 5  | sa2r      | refund tax      | refund   |
| 6  | sdf4      | refund shipping | refund   |

Таблица: транзакции

| id | type_hash | amount |
|----|-----------|--------|
| 1  | abcd      | 12     |
| 2  | dbac      | 14     |
| 3  | agft      | 19     |
| 4  | pgsk      | -20    |
| 5  | sa2r      | -12    |
| 6  | sdf4      | -7     |

Отношение - транзакция принадлежиттип транзакции

public function transactionType() : BelongsTo
{
    return $this->belongsTo(TransactionType::class, 'type_hash', 'type_hash');
}

Результат, который я ищу в таблице транзакций:

  • Сумма, агрегированная sum(amount) as amount
  • Группировка транзакций по TransactionType.category

т.е.

| Results | transactionType.category | sum(amount)   |
|---------|--------------------------|---------------|
| 1       | sale                     | 45            |
| 2       | refund                   | -39           |

Я могу получить следующую работу, но в идеале я хочу сделать все агрегации в построителе запросов, а не в коллекции:

Transaction::selectRaw('sum(amount) as amount')
    ->with('transactionType')
    ->get()
    ->groupBy('transactionType.category');

Я попробовал следующее (и варианты), но не могу заставить его работать:

Transaction::selectRaw('sum(amount) as amount')
    ->with(['transactionType' => function($query){
        $query->select('category')->groupBy('category');
    }])
    ->get();

1 Ответ

0 голосов
/ 24 апреля 2019

В сгенерированном SQL вам нужно выбрать столбец, по которому вы группируете, и вам нужно вызвать get () после groupBy, иначе вы бы вызывали groupBy для коллекции, а не для запроса застройщик объекта. Таким образом, вы должны быть в состоянии сделать:

Transaction::selectRaw('transactionType.category, sum(amount) as amount')
->with('transactionType')
->groupBy('transactionType.category')
->get();

или менее красноречивый

DB::table('transaction')
->join(
    'transaction_type',
    'transaction_type.id',
    '=',
    'transaction.transaction_type_id'
)->selectRaw('transationType.category, sum(amount)')
->groupBy('transactionTyle.category')
->get();
...