2015-08-06 3 views
5

Ich habe eine „Botschaften“ Tabelle mit den folgenden SpaltenOrder By bevor Gruppe Durch die Verwendung von Eloquent (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; 

Ich versuche, alle Nachrichten zu bekommen, wo ‚EmpfängerID‘ = $ id und Gruppierung von AbsenderID . Das Problem ist, dass die "Nachricht", die auf den Ergebnissen angezeigt wird, die ersten ist, nicht die neuesten. Ich habe versucht, von createdAt zu bestellen, aber es funktioniert nicht.

Wie kann ich vor dem Abfragen und Gruppieren der Ergebnisse nach "createdAt" bestellen? Ich möchte dies auf die Laravel-Art mit Eloquent tun.

Meine Frage:

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

Können Sie uns vielleicht zeigen, wie Ihre Anfrage in Eloquent jetzt aussieht? Vielen Dank! – Bananam00n

+0

Ja, ich habe die Frage aktualisiert. – Sergio

Antwort

1

Ich habe einen Weg gefunden, das zu tun! Im Grunde erstellen Sie eine Unterabfrage und führen sie vorher aus, so dass die Ergebnisse wie erwartet geordnet und danach gruppiert werden. Hier

ist der Code:

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

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

Es sollte etwas zusammen sein:

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

aktualisieren

Nach der Abfrage zu sehen, die Sie hinzugefügt haben, müssen Sie wahrscheinlich nur zu Fügen Sie der Funktion orderBy eine Richtung hinzu:

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

Danke für die Hilfe, aber wenn ich das mag, zeigt das Nachrichtenfeld die erste Nachricht der Gruppe an. Ich möchte das Neueste zeigen (geordnet nach createdAt oder ID DESC). – Sergio

+0

Ok, meine Antwort aktualisiert, um nur die neueste auszuwählen. – lowerends

+0

Ich habe meine Antwort basierend auf der Abfrage, die Sie zu Ihrer Frage hinzugefügt haben, erneut aktualisiert. – lowerends

10

Ich brauche nur etwas ähnliches mit einem Nachrichten-Modell zu tun. Was für mich funktionierte, war die Anwendung der unique Methode auf die zurückgegebene eloquente Sammlung.

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

Die Abfrage wird alle Meldungen bestellt Rückkehr von createdAt und die unique Methode wird es für jeden fromId zu einer Nachricht reduzieren unten. Dies ist offensichtlich nicht so performant wie die direkte Verwendung der Datenbank, aber in meinem Fall habe ich weitere Einschränkungen für die Abfrage.

Auch gibt es viele weitere nützliche Methoden mit diesen Sammlungen arbeiten: https://laravel.com/docs/5.2/collections#available-methods

2

Diese Arbeit für mich: (die Reihenfolge von createdAt im Falle entfernen createAt zusammen mit id erhöhen)

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