Laravel красноречивый запрос с суммой значений из другой таблицы по условию - PullRequest
3 голосов
/ 26 мая 2020

У меня две таблицы. Сделка и размещение. одна транзакция может иметь несколько распределений. Отношения определены следующим образом:

Внутренняя таблица распределения

class Allocation extends Model
{
    public function transaction_fk(){
        return $this->belongsTo('App\Models\Transaction','transaction_id');
    }
}

Внутренняя таблица транзакций

class Transaction extends Model
{
    public function allocations() {
        return $this->hasMany('App\Models\Allocation');
    }
}

Мне нужно запросить все строки из таблицы транзакций с определенным идентификатором вместе с суммой распределений для этой строки транзакции с суммой итогов распределения, если общая сумма транзакций не равна сумме итогов распределения . Что-то вроде следующего:

Transaction::where('id',$id)->where('amount','!==','sum(allocations.amount)')->with('balance' as 'sum(allocations.amount)')->get();

Этот запрос не работает. Что мне не хватает?

Мне удалось сделать это как простой запрос, который я перебрал, сделал второй запрос и добавил в список. Это дает мне правильный результат. Как видите, это многословно и медленнее. Мне нужно сделать это сразу, запросив базу данных один раз.

 $transactions2 = Transaction::where('contact_type','supplier')
    ->where('contact_id',$ehead->supplier_id)
    ->get();

    $transactions = [];
    foreach ($transactions2 as $item) {
       $sum = Allocation::where('transaction_id',$item['id'])->get()->sum('amount');
       if($item['amount'] !== $sum){
        $item->unallocated_amount = $sum;
        array_push($transactions, $item);
       }

    }

1 Ответ

0 голосов
/ 26 мая 2020

Вы должны использовать функции groupBy и агрегирования, если хотите сделать это в одном запросе.

$items = Transaction::query()
            ->join('allocations', 'transactions.id', '=', 'allocations.transaction_id')
            ->groupBy('transactions.id')
            ->having('transactions.amount', '<>', 'sum(allocations.amount)')
            ->whereIn('transactions.id', $transactions2)
            ->select('transactions.*')
            ->get();
...