Laravel Eloquent Suma kolumny relacji


111

Pracowałem nad aplikacją Shoppingcart i teraz doszedłem do następującego problemu.

Jest Użytkownik, Produkt i Obiekt Koszyk.
- Tabela Cart zawiera tylko następujące kolumny: „id”, „user_id”, „product_id” i timestamps.
- Model użytkownika „hasMany” Carts (ponieważ użytkownik może przechowywać wiele produktów).
- CartModel „nalezy do” użytkownika i CartModel „hasMany” produktów.

Teraz do obliczenia całkowitej produkty mogę po prostu zadzwonić: Auth::user()->cart()->count().

Moje pytanie brzmi: Jak uzyskać SUMA () cen (kolumna produktu) produktów w koszyku tego Użytkownika?
Chciałbym to osiągnąć za pomocą Eloquent, a nie za pomocą zapytania (głównie dlatego, że uważam, że jest o wiele czystsze).

Odpowiedzi:


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

Dokumentacja jest trochę lekka dla niektórych Collectionmetod, ale wszystkie agregaty konstruktora zapytań są pozornie dostępne poza avg()tymi, które można znaleźć na http://laravel.com/docs/queries#aggregates .


wow dzięki za tę szybką odpowiedź. Teraz mówi tylko, że nie ma kolumny cen. Wygląda na to, że wymownie w ogóle nie patrzy się na tę tabelę produktów ...
— theAdmiral

3
Właściwie to ma sens, musisz dodać tabelę produktów do relacji, przepraszam. Wypróbuj $sum = Auth::user()->cart()->products()->sum('price');lub cokolwiek w kolumnie ceny znajduje się w tabeli produktów.
— user1669496,

1
To zadziałało dla mnie! Przestałem korzystać z klas wózków. Zarówno użytkownik, jak i produkt mają teraz metodę contribToMany (). Teraz mogę użyć ceny: {{Auth :: user () -> products-> sum ('price')}} Thanx, ten przypadek został rozwiązany.
— Admirał

9
Coś tu jest nie tak - twoje łącze odnosi się do stosowania funkcji agregujących do zapytań bazy danych, ale products->sumsugeruje, że jest to suma wywołań na obiekcie kolekcji, a nie na obiekcie konstruktora zwracanym przez products (). Warto wyjaśnić, który z nich masz na myśli, i najlepiej podać link, aby wyjaśnić oba.
— Benubird

1
@ user3253002 używając relacji bez nawiasów, ...->products->...wyśle ​​zapytanie do bazy danych, aby pobrać wszystkie produkty powiązane z bieżącym modelem, a następnie będzie pracować z tą kolekcją w pamięci. Użycie ...->products()->...po prostu modyfikuje budowane zapytanie bez wykonywania go, dopóki nie ->sum()zostanie wywołane coś takiego, co może być bardziej wydajne, ponieważ pozwala uniknąć przesyłania niepotrzebnych informacji z bazy danych do pamięci.
— Siegen

62

to nie jest twoja odpowiedź, ale dla tych, którzy przyjeżdżają tutaj, szukając rozwiązania innego problemu. Chciałem warunkowo uzyskać sumę kolumny powiązanej tabeli. W mojej bazie danych umowy zawiera wiele działań. Chciałem uzyskać sumę „suma_kwoty” z tabeli Działania, gdzie działania.deal_id = deal.id i działania.status = zapłacone, więc zrobiłem to.

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

wraca

"paid_sum_count" => "320.00"

w atrybucie okazji.

To jest teraz suma, której chciałem nie liczyć.


4
W wielu przypadkach jest to najlepsze rozwiązanie, ponieważ można sortować według niego bez konieczności pobierania wszystkich rekordów.
— Sabrina Leggett

15

Próbowałem zrobić coś podobnego, co zajęło mi dużo czasu, zanim mogłem rozgryźć funkcję collect (). Więc możesz mieć coś w ten sposób:

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

To daje sumę wszystkich pozycji.


4
nazwa funkcji to właściwiecollect()
— Leonardo Beal

prawdopodobnie lepiej będzie po prostu zapętlić tablicę. collect()służy do wzbogacenia tablicy w obiekt kolekcji, ale jeśli nie masz kolekcji w pierwszej kolejności, może być lepiej użyć po prostu tablicy surowej
— Flame

0

Również za pomocą konstruktora zapytań

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

Aby uzyskać podsumowanie wszystkich wartości stawek wewnątrz stawek tabeli.

Aby uzyskać podsumowanie produktów użytkownika.

DB::table("users")->get()->sum("products")
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.