Метод withSum
Метод withSum применяется к запросу Eloquent для загрузки суммы значений указанного столбца из связанных записей. В качестве первого параметра передаётся имя связи, вторым - имя колонки, сумму которой необходимо подсчитать. Третий параметр опциональный и позволяет задать псевдоним для результирующего поля. Метод возвращает тот же запрос с добавленным агрегирующим условием.
Синтаксис
<?php
Model::withSum($relation, $column, $alias);
?>
Пример
Предположим, у нас есть модель User, которая имеет связь hasMany с моделью Order. Давайте получим сумму заказов для каждого пользователя:
<?php
namespace AppHttpControllers;
use AppModelsUser;
class UserController extends Controller
{
public function index()
{
$users = User::withSum('orders', 'total')->get();
foreach ($users as $user) {
echo "User: " . $user->name . ", orders_sum: " . $user->orders_sum_total;
}
}
}
?>
Результат выполнения кода:
"User: John, orders_sum: 1500"
"User: Jane, orders_sum: 2300"
"User: Bob, orders_sum: 800"
Пример с псевдонимом
Можно задать собственное имя для результирующего поля с помощью третьего параметра:
<?php
namespace AppHttpControllers;
use AppModelsUser;
class OrderController extends Controller
{
public function index()
{
$users = User::withSum('orders', 'amount', 'total_amount')->get();
foreach ($users as $user) {
echo "User: " . $user->name . ", total_amount: " . $user->total_amount;
}
}
}
?>
Результат выполнения кода:
"User: John, total_amount: 1500"
"User: Jane, total_amount: 2300"
"User: Bob, total_amount: 800"
Пример с условиями на связанные записи
Метод withSum можно комбинировать с методами фильтрации для подсчёта суммы только определенных связанных записей:
<?php
namespace AppHttpControllers;
use AppModelsCategory;
class ProductController extends Controller
{
public function index()
{
$categories = Category::withSum(['products' => function ($query) {
$query->where('status', 'active');
}], 'price', 'active_products_sum')->get();
foreach ($categories as $category) {
echo "Category: " . $category->name . ", active_products_sum: " . $category->active_products_sum;
}
}
}
?>
Результат выполнения кода:
"Category: Electronics, active_products_sum: 5000"
"Category: Books, active_products_sum: 1200"
"Category: Clothing, active_products_sum: 3500"
Пример с множественными суммами
Можно использовать несколько вызовов withSum для подсчёта сумм по разным связям или столбцам:
<?php
namespace AppHttpControllers;
use AppModelsCustomer;
class ReportController extends Controller
{
public function index()
{
$customers = Customer::withSum('invoices', 'amount', 'invoices_total')
->withSum('payments', 'amount', 'payments_total')
->get();
foreach ($customers as $customer) {
echo "Customer: " . $customer->name . ", Invoices total: " . $customer->invoices_total . ", Payments total: " . $customer->payments_total;
}
}
}
?>
Результат выполнения кода:
"Customer: Alice, Invoices total: 10000, Payments total: 4500"
"Customer: Bob, Invoices total: 5000, Payments total: 2000"
"Customer: Charlie, Invoices total: 8000, Payments total: 8000"