Laravel Eloquent Somma della colonna della relazione


111

Ho lavorato a un'applicazione per carrelli e ora sono arrivato al seguente problema ..

C'è un oggetto Utente, un Prodotto e un Carrello.
- La tabella Carrello contiene solo le seguenti colonne: "id", "user_id", "product_id" e timestamp.
- Il UserModel "hasMany" Carrelli (perché un utente può memorizzare più prodotti).
- Il CartModel "appartiene a" un Utente e CartModel "haMolti" Prodotti.

Ora per il calcolo totale dei prodotti posso solo chiamare: Auth::user()->cart()->count().

La mia domanda è: come posso ottenere la SOMMA () dei prezzi (una colonna di prodotto) dei prodotti nel carrello da questo Utente?
Vorrei farlo con Eloquent e non usando una query (principalmente perché credo che sia molto più pulito).

Risposte:


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

La documentazione è un po 'leggera per alcuni dei Collectionmetodi, ma tutti gli aggregati del generatore di query sono apparentemente disponibili oltre a avg()quello che può essere trovato su http://laravel.com/docs/queries#aggregates .


wow grazie per quella rapida risposta. Ora dice solo che non ci sono colonne dei prezzi. Sembra che eloquente non stia guardando affatto la tabella del prodotto ...
Ammiraglio

3
In realtà ha senso, devi aggiungere la tabella dei prodotti alla relazione, mi dispiace. Prova $sum = Auth::user()->cart()->products()->sum('price');o qualunque sia la colonna del prezzo sulla tabella dei prodotti.
user1669496

1
Ha funzionato per me! Ho smesso di usare le cartclass. Sia l'utente che il prodotto ora dispongono di un metodo appartieneToMany (). Ora posso usare il prezzo: {{Auth :: user () -> products-> sum ('price')}} Grazie, questo caso è stato risolto.
Ammiraglio

9
Qualcosa non va bene qui: il tuo collegamento si riferisce all'applicazione di funzioni aggregate alle query del database, ma products->sumimplica che si tratta di una chiamata sum su un oggetto di raccolta, piuttosto che sull'oggetto generatore restituito da products (). Vale la pena chiarire quale si intende qui e, idealmente, fornire un collegamento per spiegare entrambi.
Benubird

1
@ user3253002 utilizzando una relazione senza parentesi ...->products->...interrogherà il database per ottenere tutti i prodotti correlati del modello corrente e quindi lavorerà con quella raccolta in memoria. L'utilizzo ...->products()->...modifica semplicemente la query in fase di compilazione senza eseguirla fino a quando non ->sum()viene chiamato qualcosa di simile . Quest'ultimo può essere più efficiente, poiché evita di trasferire informazioni non necessarie dal database alla memoria.
Siegen

62

questa non è la tua risposta, ma è per coloro che vengono qui alla ricerca di una soluzione per un altro problema. Volevo ottenere la somma di una colonna della tabella correlata in modo condizionale. Nel mio database Deals ha molte attività che volevo ottenere la somma di "amount_total" dalla tabella Activities dove activities.deal_id = deal.id e activities.status = paid così ho fatto questo.

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

ritorna

"paid_sum_count" => "320.00"

nell'attributo Deals.

Questa ora è la somma che volevo ottenere, non il conteggio.


4
Questo è il migliore in molti casi perché puoi ordinare in base a esso senza dover ottenere tutti i record.
Sabrina Leggett

15

Ho provato a fare qualcosa di simile, che mi ci è voluto molto tempo prima di poter capire la funzione collect (). Quindi puoi avere qualcosa in questo modo:

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

Questo ti darà la somma totale di tutti gli articoli.


4
il nome della funzione è in realtàcollect()
Leonardo Beal

probabilmente farai meglio a eseguire il loop dell'array. collect()viene utilizzato per arricchire un array in un oggetto di raccolta, ma se non si dispone di una raccolta in primo luogo potrebbe essere meglio utilizzare solo l'array grezzo
Flame

0

Anche utilizzando il generatore di query

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

Per ottenere la somma di tutti i valori delle tariffe all'interno delle tariffe della tabella.

Per ottenere il riepilogo dei prodotti degli utenti.

DB::table("users")->get()->sum("products")
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.