Столбец Laravel Eloquent Sum of Relationship


112

Я работал над приложением для тележки, и теперь я столкнулся со следующей проблемой ..

Есть объекты "Пользователь", "Товар" и "Корзина".
- Таблица корзины содержит только следующие столбцы: «id», «user_id», «product_id» и временные метки.
- UserModel "hasMany" тележек (поскольку пользователь может хранить несколько продуктов).
- Модель CartModel "принадлежит" пользователю, а CartModel "hasMany" продуктов.

Теперь , чтобы вычислить общее количество продуктов я могу просто позвонить: Auth::user()->cart()->count().

Мой вопрос: как я могу получить СУММУ () цен (столбец продукта) продуктов в корзине этого пользователя?
Я хотел бы добиться этого с помощью Eloquent, а не с помощью запроса (в основном потому, что я считаю, что он намного чище).

Ответы:


221
Auth::user()->products->sum('price');

Документация немного освещает некоторые Collectionметоды, но все агрегаты построителя запросов, похоже, доступны, кроме того, avg()что можно найти по адресу http://laravel.com/docs/queries#aggregates .


вау, спасибо за быстрый ответ. Теперь там просто говорится, что столбца с ценами нет. Похоже, красноречивый человек вообще не смотрит на эту таблицу продуктов ...
Адмирал

3
На самом деле это имеет смысл, извините, вам нужно добавить таблицу продуктов в отношения. Попробуйте $sum = Auth::user()->cart()->products()->sum('price');или любой другой столбец цен в таблице продуктов.
user1669496

1
Это сработало для меня! Я перестал пользоваться классами телеги. И у пользователя, и у продукта теперь есть метод ownToMany (). Теперь я могу использовать price: {{Auth :: user () -> products-> sum ('price')}} Спасибо, этот случай решен.
theAdmiral

10
Что-то здесь не совсем правильное - ваша ссылка относится к применению агрегатных функций к запросам базы данных, но products->sumподразумевает, что это сумма вызовов для объекта коллекции, а не для объекта построителя, возвращаемого с помощью products (). Стоит уточнить, какой из них вы имеете в виду, и в идеале предоставить ссылку, чтобы объяснить оба.
Benubird 05

1
@ user3253002 с использованием отношения без скобок ...->products->...будет запрашивать базу данных, чтобы получить все связанные продукты текущей модели, а затем работать с этой коллекцией в памяти. Использование ...->products()->...просто изменяет ->sum()строящийся запрос, не выполняя его до тех пор, пока не будет вызвано что-то подобное. Последнее может быть более эффективным, поскольку позволяет избежать переноса ненужной информации из базы данных в память.
Зиген

62

это не ваш ответ, это для тех, кто пришел сюда в поисках решения другой проблемы. Я хотел условно получить сумму столбца связанной таблицы. В моей базе данных Deals есть много действий. Я хотел получить сумму «amount_total» из таблицы Activities, где activity.deal_id = deal.id и activity.status = платные, поэтому я сделал это.

$query->withCount([
'activity AS paid_sum' => function ($query) {
            $query->select(DB::raw("SUM(amount_total) as paidsum"))->where('status', 'paid');
        }
    ]);

он возвращается

"paid_sum_count" => "320.00"

в атрибуте Сделки.

Это сумма, которую я хотел получить, а не счет.


4
Это лучший вариант во многих случаях, потому что вы можете сортировать по нему, не получая всех записей.
Сабрина Леггетт

15

Я попытался сделать что-то подобное, что заняло у меня много времени, прежде чем я смог разобраться в функции collect (). Таким образом, у вас может получиться что-то такое:

collect($items)->sum('amount');

Это даст вам общую сумму всех предметов.


4
на самом деле название функцииcollect()
Леонардо Бил

вам, вероятно, лучше просто зациклить массив. collect()используется для обогащения массива в объект коллекции, но если у вас вообще нет коллекции, может быть лучше просто использовать необработанный массив
Flame

0

Также с помощью построителя запросов

DB::table("rates")->get()->sum("rate_value")

Для получения суммы всех значений ставок внутри таблицы ставок.

Чтобы получить суммирование пользовательских продуктов.

DB::table("users")->get()->sum("products")
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.