Wählen Sie Letzte Zeile in der Tabelle

163

Ich möchte die zuletzt in meine Tabelle eingefügte Datei abrufen. Ich weiß, dass die Methode first()existiert und liefert Ihnen die erste Datei in der Tabelle, aber ich weiß nicht, wie Sie die letzte Einfügung erhalten.

Carlos Suñol
quelle
Siehe auch stackoverflow.com/questions/33321447/… So sortieren Sie eine bestehende Beziehung (hasMany)
Tarek Adam
Dies ist für alle, die nach Laravel fragen und antworten. Denken Sie daran, dass es wichtig ist anzugeben, über welche Laravel-Version Sie sprechen. Im Allgemeinen weisen Version 4 und 5 Unterschiede auf und ältere Versionen auch.
Heroselohim

Antworten:

223

Sie müssen nach demselben Feld bestellen, das Sie gerade bestellen, aber absteigend. Wenn Sie beispielsweise einen Zeitstempel haben, als der Upload aufgerufen wurde upload_time, würden Sie so etwas tun.

Für Pre-Laravel 4

return DB::table('files')->order_by('upload_time', 'desc')->first();

Ab Laravel 4

return DB::table('files')->orderBy('upload_time', 'desc')->first();

Ab Laravel 5.7

return DB::table('files')->latest('upload_time')->first();

Dadurch werden die Zeilen in der Dateitabelle nach Upload-Zeit, absteigender Reihenfolge und der ersten sortiert . Dies ist die zuletzt hochgeladene Datei.

Joachim Isaksson
quelle
15
Für Laravel 4 sollte dies orderBynicht seinorder_by
Jared Eitnier
9
Wenn Sie ORM verwenden, ist dies ein korrekter Weg:User::orderby('created_at', 'desc')->first();
Cas Bloem
1
Laravel 5.x =orderBy('created_at', 'desc')
0x1ad2
9
Warum verwenden Sie die Spalte created_at? Die Verwendung der Primärschlüssel-ID ist viel schneller. Laravel 5.x Files::orderBy(id', 'desc')->first();Reihenfolge nach Datum funktioniert länger, da das Datum eine Zeichenfolge ist und höchstwahrscheinlich nicht indiziert ist. Während der Primärschlüssel indiziert ist und superschnell funktioniert. Selbst wenn created_at indiziert ist, handelt es sich um eine indizierte Zeichenfolge und im Falle einer primären nicht um INT. Indexzeichenfolge hat weniger Leistung.
KorbenDallas
4
@KorbenDallas Kommentar sollte die Antwort sein, da Sie manchmal orderBy('created_at', 'desc')nicht die letzte Zeile erhalten. Beispiel: 3 Zeilen können genau den gleichen TIMESTAMP-Wert haben und mit orderBy('created_at', 'desc')Ihnen erhalten Sie die erste der 3 (was nicht unbedingt die letzte Zeile ist)
viery365
111

Verwenden Sie das neueste von Laravel bereitgestellte Zielfernrohr.

Model::latest()->first();

Auf diese Weise rufen Sie nicht alle Datensätze ab. Eine schönere Abkürzung zu orderBy.

Nick
quelle
7
Beachten Sie, dass diese Methode die automatisch generierte created_atSpalte ($timestamps = true)im Modell verwendet, aber auf Wunsch deaktiviert werden kann, so dass Sie einen Fehler haben würden, wenn nicht definiert
Plotisateur
Ich verwende Laravel 5.7 und versuche, dies auf einem Modell zu tun, ruft immer noch alle Datensätze für mich ab.
CJ Dennis
1
Beachten Sie, dass, wenn Sie mehrere Datensätze innerhalb derselben Sekunde hinzugefügt haben, die Erstellungszeit für diese Datensätze dieselbe ist und der von latest () zurückgegebene Datensatz daher möglicherweise nicht der Datensatz ist, den Sie erwarten.
F3CP
Beachten Sie, dass Sie keine Spalte 'created_at' benötigen. Sie können angeben, aus welcher Spalte Sie die neueste Version erhalten möchten. Zum Beispiel: Model :: latest ('dateColumn') -> first ();
Tom
Dies kann dazu führen, dass die tatsächliche letzte Zeile nicht abgerufen wird, wenn zwei Zeilen innerhalb von 1 Sekunde eingefügt werden (was tatsächlich zu Problemen beim Testen von Einheiten geführt hat).
Chili
75

Sie haben nie erwähnt, ob Sie Eloquent, Laravels Standard-ORM, verwenden oder nicht. Nehmen wir an, Sie möchten den neuesten Eintrag einer Benutzertabelle von created_at erhalten. Sie könnten wahrscheinlich Folgendes tun:

User::orderBy('created_at', 'desc')->first();

Zuerst werden die Benutzer absteigend nach dem Feld created_at sortiert, und dann wird der erste Datensatz des Ergebnisses erstellt.

Dadurch erhalten Sie eine Instanz des Benutzerobjekts und keine Sammlung. Um diese Alternative nutzen zu können, benötigen Sie natürlich ein Benutzermodell, das die Eloquent-Klasse erweitert. Das mag etwas verwirrend klingen, aber es ist sehr einfach, loszulegen, und ORM kann sehr hilfreich sein.

Weitere Informationen finden Sie in der offiziellen Dokumentation, die ziemlich umfangreich und detailliert ist.

Luis Milanese
quelle
42

Details zum letzten Datensatz abrufen

  1. Model::all()->last(); oder
  2. Model::orderBy('id', 'desc')->first();

Um die letzte Datensatz-ID zu erhalten

  1. Model::all()->last()->id; oder
  2. Model::orderBy('id', 'desc')->first()->id;
Haseena PA
quelle
14

Laravel Sammlungen hat Methode zuletzt

Model::all() -> last(); // last element 
Model::all() -> last() -> pluck('name'); // extract value from name field. 

Dies ist der beste Weg, dies zu tun.

mdamia
quelle
16
Ich wollte nur darauf hinweisen, dass die all()Methode tatsächlich alle Elemente lädt. Dies funktioniert nicht auf einer Tabelle mit Millionen von Datensätzen.
Steven Jeffries
1
Zusätzlich zu Steven Jeffries Kommentar möchte ich darauf hinweisen, dass der Aufruf last()eine einzelne eloquente Instanz und keine Sammlung pluck()Model::all()->pluck('name')name
zurückgibt. Wenn Sie diesen
5
Diese Methode ist eigentlich schlimmer. Sie rufen das letzte Raw mithilfe der PHP-Ausführung ab, anstatt es als DB-Ebene auszuführen. Was ist, wenn der Tisch Millionen von Rohdaten enthält, dann wissen Sie, wie ineffizient er sein kann?
Bhaskar Dabhi
Dies ist der beste Weg, dies zu tun. - Nein! Nie war, wird nie. Sie würden alle Zeilen laden, anstatt nur die, die Sie benötigen.
René Roth
11

Versuche dies :

Model::latest()->get();
Mark-Hero
quelle
1
Dies gibt mehrere Zeilen zurück. Er braucht eine einzige Reihe. first () hilft ihm mit der orderBy () -Klausel.
Tahir Afridi
Dies kann dazu führen, dass die tatsächliche letzte Zeile nicht abgerufen wird, wenn zwei Zeilen innerhalb von 1 Sekunde eingefügt werden (was tatsächlich zu Problemen beim Testen von Einheiten geführt hat).
Chili
1
Bei einer großen Tabelle führt dies zu einer Ausnahme wegen Speichermangels, da, wie bei @TahirAfridi erwähnt, alle Zeilen in den Speicher geladen werden.
Rihards
6

Sie können den neuesten von Laravel bereitgestellten Bereich für das Feld verwenden, das Sie filtern möchten. Nehmen wir an, es wird nach ID sortiert und dann:

Model::latest('id')->first();

Auf diese Weise können Sie eine Bestellung nach vermeiden created_at bei Laravel standardmäßig Feldern zu .

tiaguinhow
quelle
5

Verwenden Sie den folgenden Code, um die letzten Datensatzdetails abzurufen:

Model::where('field', 'value')->get()->last()
Jimuel Palaca
quelle
Benutze es nicht. Dies ist eine sehr schlechte Vorgehensweise. Es gibt einen Bereich von latest (), der direkten Zugriff auf die zuletzt eingefügte Zeile bietet.
Working Pig
3

Eine andere ausgefallene Möglichkeit, dies in Laravel 6.x zu tun (unsicher, muss aber auch für 5.x funktionieren):

DB::table('your_table')->get()->last();

Sie können auch auf Felder zugreifen:

DB::table('your_table')->get()->last()->id;

Towelie
quelle
Funktioniert auch für mich in Laravel 5.8, habe gerade die Antwort gepostet, bevor ich deine
sehe
1
Eine kleine Erklärung, wie Laravel dies hinter den Kulissen tut und warum dies für große Datenmengen gefährlich ist. Die get()Methode ruft alles ab your_tableund generiert eine Sammlung. Die last()Methode ruft das letzte Element aus dieser Sammlung ab. Sie haben also bereits alle Daten aus der Tabelle in Ihrem Speicher geladen (fehlerhaft). Sie sollten einfach "DB :: table (" items ") -> latest () -> first ();" hinter den Kulissen "orderBy ($ column," desc ")" ausführen und den ersten Datensatz abrufen.
Anuj Shrestha
2

Model($where)->get()->last()->id

Blenden
quelle
1

Wenn Sie nach der tatsächlichen Zeile suchen, die Sie gerade mit Laravel 3 und 4 eingefügt haben, wenn Sie eine saveoder eine createAktion für ein neues Modell ausführen, wie z.

$user->save();

-oder-

$user = User::create(array('email' => '[email protected]'));

Anschließend wird die eingefügte Modellinstanz zurückgegeben und kann für weitere Aktionen verwendet werden, z. B. zum Umleiten auf die Profilseite des gerade erstellten Benutzers.

Das Suchen nach dem zuletzt eingefügten Datensatz funktioniert auf einem System mit geringer Lautstärke fast immer. Wenn Sie jedoch gleichzeitig Einfügungen vornehmen müssen, können Sie am Ende nachfragen, um den falschen Datensatz zu finden. Dies kann in einem Transaktionssystem, in dem mehrere Tabellen aktualisiert werden müssen, zu einem echten Problem werden.

bloggidy
quelle
1

Irgendwie scheint all das in Laravel 5.3 nicht für mich zu funktionieren, also habe ich mein eigenes Problem gelöst mit:

Model::where('user_id', '=', $user_id)->orderBy('created_at', 'desc')->get();

Ich hoffe, ich kann jemanden retten.

Der Tote
quelle
1

Model::where('user_id', $user_id)->latest()->get()->first(); Wenn Sie es verwenden, wird nur ein Datensatz zurückgegeben. Wenn es nicht gefunden wird, wird es zurückgegeben null. Hoffe das wird helfen.

风声 猎猎
quelle
0

Wenn die Tabelle ein Datumsfeld enthält, ist dies ( User::orderBy('created_at', 'desc')->first();) meiner Meinung nach die beste Lösung. Aber es gibt kein Datumsfeld, Model ::orderBy('id', 'desc')->first()->id;ist die beste Lösung, da bin ich mir sicher.

Wang Xin
quelle
0

beachten Sie, dass last(), latest()nicht deterministisch sind , wenn Sie für eine sequentielle oder Ereignis / geordneten Datensatz suchen. Die letzten / letzten Datensätze können genau den gleichen created_atZeitstempel haben, und der, den Sie zurückerhalten, ist nicht deterministisch. Also mach es orderBy(id|foo)->first(). Andere Ideen / Vorschläge, wie man deterministisch sein kann, sind willkommen.

Mangonights
quelle