Pilih Baris Terakhir di Tabel


163

Saya ingin mengambil file terakhir yang dimasukkan ke meja saya. Saya tahu bahwa metode ini first()ada dan memberi Anda file pertama dalam tabel, tetapi saya tidak tahu cara mendapatkan sisipan terakhir.


Lihat juga stackoverflow.com/questions/33321447/... Cara menyortir hubungan yang sudah ada (hasMany)
Tarek Adam

Ini untuk siapa saja yang bertanya dan menjawab tentang Laravel. Ingatlah bahwa penting untuk menentukan versi Laravel mana yang Anda bicarakan. Umumnya versi 4 dan 5 memiliki perbedaan dan versi yang lebih lama juga.
Heroselohim

Jawaban:


224

Anda harus memesan dengan bidang yang sama dengan yang Anda pesan sekarang, tetapi turun. Sebagai contoh, jika Anda memiliki cap waktu ketika unggahan selesai dipanggil upload_time, Anda akan melakukan sesuatu seperti ini;

Untuk Pra-Laravel 4

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

Untuk Laravel 4 dan seterusnya

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

Untuk Laravel 5.7 dan seterusnya

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

Ini akan memesan baris dalam tabel file dengan mengunggah waktu, menurun urutan , dan mengambil yang pertama. Ini akan menjadi file yang diunggah terbaru.


15
Untuk Laravel 4 ini seharusnya orderBy, bukanorder_by
Jared Eitnier

9
Saat Anda menggunakan ORM, ini adalah cara yang benar:User::orderby('created_at', 'desc')->first();
Cas Bloem

1
Laravel 5.x =orderBy('created_at', 'desc')
0x1ad2

9
Mengapa Anda menggunakan kolom Created_at? Jauh lebih cepat untuk menggunakan ID kunci utama. Laravel 5.x Files::orderBy(id', 'desc')->first();Urutan menurut tanggal berfungsi lebih lama karena tanggal adalah string dan kemungkinan besar tidak diindeks. Sementara primary key diindeks dan berfungsi super cepat. Bahkan jika create_at diindeks, itu diindeks string dan bukan INT dalam kasus primer. String indeks memiliki kinerja lebih sedikit.
KorbenDallas

4
Komentar @KorbenDallas harus menjadi jawaban karena terkadang orderBy('created_at', 'desc')tidak memberi Anda baris terakhir. Contoh: 3 baris dapat memiliki nilai TIMESTAMP yang persis sama dan orderBy('created_at', 'desc')Anda akan mendapatkan yang pertama dari 3 (yang belum tentu merupakan baris terakhir)
viery365

111

Gunakan ruang lingkup terbaru yang disediakan oleh Laravel di luar kotak.

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

Dengan begitu Anda tidak mengambil semua catatan. Pintasan yang lebih baik untuk memesan oleh.


7
Perhatikan bahwa metode ini menggunakan created_atkolom yang dibuat secara otomatis ($timestamps = true)dalam Model, tetapi dapat dinonaktifkan sesuai keinginan sehingga Anda akan memiliki kesalahan jika tidak terdefinisi
Plotisateur

Saya menggunakan Laravel 5.7 dan mencoba melakukan ini pada Model masih mengambil semua catatan untuk saya.
CJ Dennis

1
Perhatikan bahwa jika Anda memiliki beberapa catatan yang ditambahkan dalam detik yang sama, waktu create_at akan sama untuk catatan ini dan oleh karena itu catatan yang dikembalikan oleh latest () mungkin bukan catatan yang Anda harapkan.
F3CP

Perhatikan bahwa Anda tidak memerlukan kolom 'Created_at'. Anda dapat menentukan dari kolom apa yang Anda inginkan terbaru. Misalnya: Model :: latest ('dateColumn') -> first ();
Tom

Ini mungkin gagal untuk mendapatkan baris terakhir yang sebenarnya jika dua baris dimasukkan dalam 1 detik (sebenarnya menyebabkan masalah dalam pengujian unit).
cabai

75

Anda tidak pernah menyebutkan apakah Anda menggunakan Eloquent, ORM default Laravel atau tidak. Jika ya, misalkan Anda ingin mendapatkan entri terbaru dari tabel Pengguna, dengan create_at, Anda mungkin bisa melakukan hal berikut:

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

Pertama memerintahkan pengguna dengan bidang create_at, turun, dan kemudian mengambil catatan pertama dari hasilnya.

Itu akan mengembalikan Anda sebuah instance dari objek Pengguna, bukan koleksi. Tentu saja, untuk menggunakan alternatif ini, Anda harus memiliki model Pengguna, memperluas kelas Eloquent. Ini mungkin terdengar agak membingungkan, tetapi sangat mudah untuk memulai dan ORM bisa sangat membantu.

Untuk informasi lebih lanjut, lihat dokumentasi resmi yang cukup kaya dan terperinci dengan baik.


42

Untuk mendapatkan detail catatan terakhir

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

Untuk mendapatkan id rekaman terakhir

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

14

Koleksi Laravel memiliki metode terakhir

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

Ini adalah cara terbaik untuk melakukannya.


16
Hanya ingin menunjukkan bahwa all()metode ini benar-benar memuat semua item. Ini tidak akan berfungsi di atas meja dengan jutaan catatan.
Steven Jeffries

1
Selain komentar Steven Jeffries, saya ingin menunjukkan bahwa pemanggilan last()mengembalikan satu instance Eloquent dan bukan Collection, dan pemanggilan pluck()yang sama dengan pemanggilan Model::all()->pluck('name'), oleh karena itu mengembalikan nameatribut dari semua baris dalam tabel
ivcandela

5
Metode ini sebenarnya lebih buruk. Anda mengambil mentah terakhir menggunakan eksekusi PHP alih-alih melakukannya sebagai tingkat DB. Bagaimana jika meja memiliki jutaan bahan mentah, maka Anda tahu seberapa tidak efisiennya?
Bhaskar Dabhi

Ini adalah cara terbaik untuk melakukannya. - Tidak! Tidak pernah, tidak akan pernah. Anda akan memuat semua baris, bukan hanya yang Anda butuhkan.
René Roth

11

Coba ini :

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

1
Ini akan mengembalikan beberapa baris. Dia membutuhkan satu baris. first () akan membantunya dengan klausa orderBy ().
Tahir Afridi

Ini mungkin gagal untuk mendapatkan baris terakhir yang sebenarnya jika dua baris dimasukkan dalam 1 detik (sebenarnya menyebabkan masalah dalam pengujian unit).
cabai

1
Pada tabel besar ini akan menyebabkan pengecualian memori karena karena @TahirAfridi menyebutkan ini akan memuat semua baris ke dalam memori.
Rihards

6

Anda dapat menggunakan ruang lingkup terbaru yang disediakan oleh Laravel dengan bidang yang ingin Anda filter, katakanlah itu akan dipesan oleh ID, lalu:

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

Jadi dengan cara ini, Anda dapat menghindari memesan berdasarkan created_atbidang secara default di Laravel.


5

Untuk mendapatkan detail catatan terakhir, gunakan kode di bawah ini:

Model::where('field', 'value')->get()->last()

Jangan gunakan itu. Ini adalah praktik yang sangat buruk ada ruang lingkup terkini () ini menyediakan akses langsung ke baris yang dimasukkan terakhir.
Babi yang Bekerja

3

Cara mewah lain untuk melakukannya di Laravel 6.x (Tidak yakin tetapi harus bekerja untuk 5.x juga):

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

Anda juga dapat mengakses bidang:

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


Juga berfungsi untuk saya di Laravel 5.8, cukup kirimkan jawabannya sebelum melihat jawaban Anda
Dazzle

1
Sedikit penjelasan tentang bagaimana laravel melakukan ini di belakang layar dan mengapa ini berbahaya untuk kumpulan data besar, get()metode akan mengambil semuanya dari your_tabledan menghasilkan Koleksi dan last()metode akan mendapatkan item terakhir dari koleksi itu. Jadi Anda sudah memiliki semua data dari tabel yang dimuat di memori Anda (buruk). Anda cukup menggunakan `DB :: table ('items') -> latest () -> first ();` di belakang layar ia menjalankan `orderBy ($ kolom, 'desc')` dan ambil catatan pertama.
Anuj Shrestha


1

Jika Anda mencari baris aktual yang baru saja Anda masukkan dengan Laravel 3 dan 4 ketika Anda melakukan saveatau melakukan createtindakan pada model baru seperti:

$user->save();

-atau-

$user = User::create(array('email' => 'example@gmail.com'));

maka instance model yang dimasukkan akan dikembalikan dan dapat digunakan untuk tindakan lebih lanjut seperti mengarahkan ulang ke halaman profil pengguna yang baru saja dibuat.

Mencari catatan yang disisipkan terakhir berfungsi pada sistem volume rendah akan berfungsi hampir sepanjang waktu, tetapi jika Anda harus memasukkan masuk pada saat yang sama, Anda dapat berakhir meminta untuk menemukan catatan yang salah. Ini benar-benar dapat menjadi masalah dalam sistem transaksional di mana beberapa tabel perlu diperbarui.


1

Entah bagaimana semua hal di atas sepertinya tidak bekerja untuk saya di laravel 5.3, jadi saya memecahkan masalah saya sendiri menggunakan:

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

berharap bisa menyelamatkan seseorang.


1

Gunakan Model::where('user_id', $user_id)->latest()->get()->first(); itu akan mengembalikan hanya satu catatan, jika tidak ditemukan, itu akan kembali null. Semoga ini bisa membantu.


0

Jika tabel memiliki bidang tanggal, ini ( User::orderBy('created_at', 'desc')->first();) adalah solusi terbaik, saya pikir. Tetapi tidak ada bidang tanggal, Model ::orderBy('id', 'desc')->first()->id;adalah solusi terbaik, saya yakin.


0

Perlu diketahui bahwa last(), latest()tidak deterministik jika Anda mencari catatan berurutan atau peristiwa / dipesan. Catatan terakhir / terakhir dapat memiliki created_atstempel waktu yang sama persis , dan yang Anda dapatkan kembali tidak deterministik. Begitu juga orderBy(id|foo)->first(). Gagasan / saran lain tentang bagaimana menjadi deterministik dapat diterima.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.