Красноречивый запрос Laravel с суммой значений из другой таблицы при условии

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

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

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);
       }

    }

person Thaha    schedule 26.05.2020    source источник
comment
Первое, что бросается в глаза, это то, что у вас неправильное состояние. !== должен быть ‹› , но также вам может понадобиться метод Raw — laravel.com/docs/7.x/queries#raw-methods   -  person kopz    schedule 26.05.2020
comment
тебе мой ответ не помог?   -  person Mehdi    schedule 27.05.2020


Ответы (1)


Вы должны использовать функции 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();
person Mehdi    schedule 26.05.2020