2015-08-06 18 views
5

Ho una tabella "messaggi" con le seguenti colonneOrdinato per prima di Gruppo Utilizzando Eloquente (laravel)

CREATE TABLE `messages` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `fromId` int(11) NOT NULL, 
    `toId` int(11) NOT NULL, 
    `message` text NOT NULL, 
    `status` int(11) NOT NULL, 
    `device` varchar(100) NOT NULL, 
    `createdAt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=57 DEFAULT CHARSET=latin1; 

Sto cercando di ottenere tutti i messaggi in cui 'toId' = $ id e raggruppamento da identità_mittente . Il problema è che il "messaggio" mostrato sui risultati è il primo, non l'ultimo. Ho provato a ordinare da creato, ma non funziona.

Come è possibile ordinare da "createdAt" prima di eseguire query e raggruppare i risultati? Voglio farlo nel modo laravel usando Eloquent.

La mia domanda:

$chats = Message::with('sender','recipient') 
     ->where('toId',$id) 
     ->orderBy('createdAt') 
     ->groupBy('fromId') 
     ->paginate(10) 
+0

Puoi mostrarci come appare la tua query in Eloquent? Grazie! – Bananam00n

+0

Sì, ho aggiornato la domanda. – Sergio

risposta

1

Ho trovato un modo per farlo! Fondamentalmente, creando una subquery e eseguendola prima, in modo che i risultati siano ordinati come previsto e raggruppati dopo.

Ecco il codice:

$sub = Message::orderBy('createdAt','DESC'); 

$chats = DB::table(DB::raw("({$sub->toSql()}) as sub")) 
    ->where('toId',$id) 
    ->groupBy('fromId') 
    ->get(); 
1

dovrebbe essere qualcosa di simile a questo:

Message::whereToId($id)->groupBy('fromId')->latest('createdAt')->first(); 

Aggiornamento

Dopo aver visto la query che hai aggiunto, probabilmente solo bisogno di aggiungi una direzione alla funzione orderBy, in questo modo:

$chats = Message::with('sender','recipient') 
    ->select(DB::raw('*, max(createdAt) as createdAt')) 
    ->where('toId',$id) 
    ->orderBy('createdAt', 'desc') 
    ->groupBy('fromId') 
    ->paginate(10) 
+1

Grazie per l'aiuto ma quando lo faccio, il campo messaggio mostra il primo messaggio del gruppo. Voglio mostrare l'ultimo (ordinato da creato o ID DESC). – Sergio

+0

Ok, ho aggiornato la mia risposta per scegliere solo l'ultima. – lowerends

+0

Ho aggiornato di nuovo la mia risposta in base alla query che hai aggiunto alla tua domanda. – lowerends

10

Ho solo bisogno di fare qualcosa di simile con un modello di messaggi. Ciò che ha funzionato per me è stato applicare il metodo unique alla raccolta eloquent restituita.

Model::where('toId', $id) 
    ->orderBy('createdAt', 'desc') 
    ->get() 
    ->unique('fromId'); 

La query restituirà tutti i messaggi in ordine di createdAt e il metodo unique ridurrà verso il basso per un solo messaggio per ogni fromId. Ovviamente non è così performante come usare direttamente il database, ma nel mio caso ho ulteriori restrizioni sulla query.

Inoltre, ci sono molti metodi più utili per lavorare con queste collezioni: https://laravel.com/docs/5.2/collections#available-methods

2

questo lavoro per me: (è possibile rimuovere l'ordine createdAt in caso createAt aumentare con id)

DB::select(DB::raw('select * from (select * from messages group by fromId desc) m order by m.createdAt')); 
Problemi correlati