Wybierz Ostatni wiersz w tabeli

163

Chciałbym odzyskać ostatni plik wstawiony do mojej tabeli. Wiem, że metoda first()istnieje i udostępnia pierwszy plik w tabeli, ale nie wiem, jak uzyskać ostatnią wstawkę.

Carlos Suñol
źródło
Zobacz także stackoverflow.com/questions/33321447/… Jak posortować istniejący związek (hasMany)
Tarek Adam
To jest dla każdego, kto pyta i odpowiada na temat Laravel. Pamiętaj, że ważne jest, aby określić, o której wersji Laravela mówisz. Ogólnie wersje 4 i 5 mają różnice i starsze wersje.
Heroselohim

Odpowiedzi:

224

Będziesz musiał zamawiać według tego samego pola, które składasz do tej pory, ale malejąco. Na przykład, jeśli masz sygnaturę czasową, kiedy wysyłanie zostało wywołane upload_time, zrobiłbyś coś takiego;

Dla wersji Pre-Laravel 4

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

Dla Laravel 4 i nowszych

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

Dla Laravel 5.7 i nowszych

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

Spowoduje to uporządkowanie wierszy w tabeli plików według czasu przesyłania, kolejności malejącej i wybranie pierwszego. Będzie to najnowszy przesłany plik.

Joachim Isaksson
źródło
15
W przypadku Laravel 4 powinno to być orderBy, a nieorder_by
Jared Eitnier
9
Kiedy używasz ORM, jest to właściwy sposób:User::orderby('created_at', 'desc')->first();
Cas Bloem
1
Laravel 5.x =orderBy('created_at', 'desc')
0x1ad2
9
Dlaczego używasz kolumny created_at? Znacznie szybsze użycie identyfikatora klucza podstawowego. Laravel 5.x Files::orderBy(id', 'desc')->first();Sortuj według daty działa dłużej, ponieważ data jest ciągiem i najprawdopodobniej nie jest indeksowana. Podczas gdy klucz podstawowy jest indeksowany i działa bardzo szybko. Nawet jeśli utworzony_at jest indeksowany, jest to indeksowany ciąg, a nie INT w przypadku podstawowego. Ciąg indeksu ma mniejszą wydajność.
KorbenDallas
4
Komentarz @KorbenDallas powinien być odpowiedzią, ponieważ czasami orderBy('created_at', 'desc')nie podaje ostatniego wiersza. Przykład: 3 wiersze mogą mieć dokładnie tę samą wartość TIMESTAMP, a wraz z orderBy('created_at', 'desc')tobą otrzymasz pierwszy z 3 (który niekoniecznie jest ostatnim wierszem)
viery365
111

Użyj najnowszej lunety dostarczonej przez Laravel po wyjęciu z pudełka.

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

W ten sposób nie odzyskasz wszystkich rekordów. Ładniejszy skrót do zamawiania według.

Nacięcie
źródło
7
Zwróć uwagę, że ta metoda korzysta z automatycznie generowanej created_atkolumny ($timestamps = true)w modelu, ale można ją wyłączyć na życzenie, aby wystąpił błąd, jeśli nie zostanie zdefiniowany
Plotisateur,
Używam Laravel 5.7 i próbuję zrobić to na Modelu, ale wciąż pobiera wszystkie rekordy dla mnie.
CJ Dennis,
1
Zauważ, że jeśli masz wiele rekordów dodanych w tej samej sekundzie, czas created_at będzie taki sam dla tych rekordów i dlatego rekord zwrócony przez latest () może nie być rekordem, którego się spodziewasz.
F3CP
Pamiętaj, że nie potrzebujesz kolumny „created_at”. Możesz określić, z której kolumny chcesz mieć najnowsze. Na przykład: Model :: latest ('dateColumn') -> first ();
Tom
Może to nie uzyskać rzeczywistego ostatniego wiersza, jeśli dwa wiersze zostaną wstawione w ciągu 1 sekundy (faktycznie spowodowało problemy w testowaniu jednostkowym).
chili
75

Nigdy nie wspomniałeś, czy używasz Eloquent, domyślnego ORM Laravela, czy nie. Jeśli tak, powiedzmy, że chcesz uzyskać najnowszy wpis w tabeli User, przez created_at, prawdopodobnie możesz wykonać następujące czynności:

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

Najpierw porządkuje użytkowników według pola created_at, malejąco, a następnie pobiera pierwszy rekord wyniku.

To zwróci instancję obiektu użytkownika, a nie kolekcję. Oczywiście, aby skorzystać z tej alternatywy, trzeba mieć model User, rozszerzający klasę Eloquent. Może się to wydawać nieco zagmatwane, ale bardzo łatwo jest zacząć, a ORM może być naprawdę pomocny.

Aby uzyskać więcej informacji, zapoznaj się z oficjalną dokumentacją, która jest dość bogata i szczegółowa.

Luis Milanese
źródło
42

Aby poznać szczegóły ostatniego rekordu

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

Aby uzyskać identyfikator ostatniego rekordu

  1. Model::all()->last()->id; lub
  2. Model::orderBy('id', 'desc')->first()->id;
Haseena PA
źródło
14

Kolekcje Laravel mają metodę ostatnią

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

To najlepszy sposób na zrobienie tego.

mdamia
źródło
16
Chciałem tylko zaznaczyć, że all()metoda faktycznie ładuje wszystkie elementy. To nie zadziała w przypadku tabeli z milionami rekordów.
Steven Jeffries
1
Oprócz komentarza Stevena Jeffriesa chciałbym zwrócić uwagę, że wywołanie last()zwraca pojedynczą instancję Eloquent, a nie Collection, a wywołanie pluck()tego jest równoznaczne z wywołaniem Model::all()->pluck('name'), a zatem zwróceniem nameatrybutu wszystkich wierszy w tabeli
ivcandela
5
Ta metoda jest faktycznie gorsza. Pobierasz ostatni plik raw używając wykonania PHP zamiast robić to na poziomie bazy danych. A co, jeśli stół ma miliony surowca, to wiesz, jak bardzo może być nieefektywny?
Bhaskar Dabhi
To najlepszy sposób na zrobienie tego. - Nie! Nigdy nie było i nigdy nie będzie. Ładowałbyś wszystkie wiersze zamiast tylko tego, którego potrzebujesz.
René Roth
11

Spróbuj tego :

Model::latest()->get();
Mark-Hero
źródło
1
Spowoduje to zwrócenie wielu wierszy. Potrzebuje jednego rzędu. first () pomoże mu z klauzulą ​​orderBy ().
Tahir Afridi
Może to nie uzyskać rzeczywistego ostatniego wiersza, jeśli dwa wiersze zostaną wstawione w ciągu 1 sekundy (faktycznie spowodowało problemy w testowaniu jednostkowym).
chili
1
W przypadku dużej tabeli spowoduje to wyjątek braku pamięci, ponieważ jak wspomniał @TahirAfridi, spowoduje to załadowanie wszystkich wierszy do pamięci.
Rihards
6

Możesz użyć najnowszego zakresu dostarczonego przez Laravel z polem, które chcesz filtrować, powiedzmy, że zostanie uporządkowane według identyfikatora, a następnie:

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

W ten sposób możesz uniknąć zamawiania według created_atpola domyślnie w Laravel.

tiaguinhow
źródło
5

Aby uzyskać szczegóły ostatniego rekordu, użyj poniższego kodu:

Model::where('field', 'value')->get()->last()
Jimuel Palaca
źródło
Nie używaj tego. Jest to bardzo zła praktyka. Jest to zakres latest (), który zapewnia bezpośredni dostęp do ostatnio wstawionego wiersza.
Working Pig
3

Kolejny fantazyjny sposób na zrobienie tego w Laravel 6.x (niepewny, ale musi działać również dla 5.x):

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

Możesz również uzyskać dostęp do pól:

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

Ręcznik
źródło
Działa również dla mnie w Laravel 5.8, właśnie opublikowałem odpowiedź, zanim zobaczyłem twoją
Dazzle
1
Małe wyjaśnienie, w jaki sposób Laravel robi to za kulisami i dlaczego jest to niebezpieczne dla dużego zestawu danych, get()metoda pobierze wszystko z your_tablei wygeneruje kolekcję, a last()metoda uzyska ostatni element z tej kolekcji. Więc będziesz mieć już wszystkie dane z tabeli załadowane do twojej pamięci (źle). Powinieneś po prostu użyć `DB :: table ('items') -> latest () -> first ();` za sceną wykona polecenie `orderBy ($ column, 'desc')` i pobierz pierwszy rekord.
Anuj Shrestha
2

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

Oślepiać
źródło
1

Jeśli szukasz rzeczywistego wiersza, który właśnie wstawiłeś za pomocą Laravel 3 i 4 podczas wykonywania akcji savelub createna nowym modelu, na przykład:

$user->save();

-lub-

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

następnie wstawiona instancja modelu zostanie zwrócona i może być użyta do dalszych działań, takich jak przekierowanie do strony profilu właśnie utworzonego użytkownika.

Wyszukiwanie ostatniego wstawionego rekordu działa na systemie o małej objętości, ale będzie działać prawie przez cały czas, ale jeśli kiedykolwiek będziesz musiał wstawiać wstawki w tym samym czasie, możesz zakończyć wyszukiwanie w celu znalezienia niewłaściwego rekordu. Może to naprawdę stać się problemem w systemie transakcyjnym, w którym wiele tabel wymaga aktualizacji.

bloggidy
źródło
1

W jakiś sposób wszystkie powyższe nie działają dla mnie w Laravel 5.3, więc rozwiązałem swój własny problem za pomocą:

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

mam nadzieję, że uda mi się kogoś wykupić.

The Dead Guy
źródło
1

Użycie Model::where('user_id', $user_id)->latest()->get()->first(); go zwróci tylko jeden rekord, jeśli nie znajdzie, zwróci null. Mam nadzieję, że to pomoże.

风声 猎猎
źródło
0

Jeśli tabela ma pole daty User::orderBy('created_at', 'desc')->first();, myślę, że to ( ) jest najlepszym rozwiązaniem. Ale nie ma pola daty Model ::orderBy('id', 'desc')->first()->id;, jestem pewien, że jest to najlepsze rozwiązanie.

wang xin
źródło
0

należy pamiętać, że last(), latest()nie są deterministyczne, jeśli szukasz kolejnego lub zdarzenia / zamówionej rekordu. Ostatnie / ostatnie rekordy mogą mieć dokładnie tę samą created_atsygnaturę czasową, a to, co otrzymujesz, nie jest deterministyczne. Więc zrób orderBy(id|foo)->first(). Inne pomysły / sugestie, jak być deterministycznym, są mile widziane.

mangonights
źródło