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ę.
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;
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.
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.
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.
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.
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.
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.
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:
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.
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.
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.
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.
Odpowiedzi:
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
Dla Laravel 4 i nowszych
Dla Laravel 5.7 i nowszych
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.
źródło
orderBy
, a nieorder_by
User::orderby('created_at', 'desc')->first();
orderBy('created_at', 'desc')
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ść.orderBy('created_at', 'desc')
nie podaje ostatniego wiersza. Przykład: 3 wiersze mogą mieć dokładnie tę samą wartość TIMESTAMP, a wraz zorderBy('created_at', 'desc')
tobą otrzymasz pierwszy z 3 (który niekoniecznie jest ostatnim wierszem)Użyj najnowszej lunety dostarczonej przez Laravel po wyjęciu z pudełka.
W ten sposób nie odzyskasz wszystkich rekordów. Ładniejszy skrót do zamawiania według.
źródło
created_at
kolumny($timestamps = true)
w modelu, ale można ją wyłączyć na życzenie, aby wystąpił błąd, jeśli nie zostanie zdefiniowanyNigdy 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:
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.
źródło
Aby poznać szczegóły ostatniego rekordu
Model::all()->last();
lubModel::orderBy('id', 'desc')->first();
Aby uzyskać identyfikator ostatniego rekordu
Model::all()->last()->id;
lubModel::orderBy('id', 'desc')->first()->id;
źródło
Kolekcje Laravel mają metodę ostatnią
To najlepszy sposób na zrobienie tego.
źródło
all()
metoda faktycznie ładuje wszystkie elementy. To nie zadziała w przypadku tabeli z milionami rekordów.last()
zwraca pojedynczą instancję Eloquent, a nie Collection, a wywołaniepluck()
tego jest równoznaczne z wywołaniemModel::all()->pluck('name')
, a zatem zwróceniemname
atrybutu wszystkich wierszy w tabeliSpróbuj tego :
źródło
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:
W ten sposób możesz uniknąć zamawiania według
created_at
pola domyślnie w Laravel.źródło
Aby uzyskać szczegóły ostatniego rekordu, użyj poniższego kodu:
źródło
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ódło
get()
metoda pobierze wszystko zyour_table
i wygeneruje kolekcję, alast()
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.Model($where)->get()->last()->id
źródło
Jeśli szukasz rzeczywistego wiersza, który właśnie wstawiłeś za pomocą Laravel 3 i 4 podczas wykonywania akcji
save
lubcreate
na nowym modelu, na przykład:-lub-
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.
źródło
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ą:
mam nadzieję, że uda mi się kogoś wykupić.
źródło
Użycie
Model::where('user_id', $user_id)->latest()->get()->first();
go zwróci tylko jeden rekord, jeśli nie znajdzie, zwrócinull
. Mam nadzieję, że to pomoże.źródło
Jeśli tabela ma pole daty
User::orderBy('created_at', 'desc')->first();
, myślę, że to ( ) jest najlepszym rozwiązaniem. Ale nie ma pola datyModel ::orderBy('id', 'desc')->first()->id;
, jestem pewien, że jest to najlepsze rozwiązanie.źródło
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_at
sygnaturę czasową, a to, co otrzymujesz, nie jest deterministyczne. Więc zróborderBy(id|foo)->first()
. Inne pomysły / sugestie, jak być deterministycznym, są mile widziane.źródło