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.

Carlos Suñol
sumber
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.

Joachim Isaksson
sumber
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.

Nick
sumber
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.

Luis Milanese
sumber
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;
Haseena PA
sumber
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.

mdamia
sumber
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();
Mark-Hero
sumber
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.

tiaguinhow
sumber
5

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

Model::where('field', 'value')->get()->last()
Jimuel Palaca
sumber
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;

Handuk
sumber
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
2

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

Mempesona
sumber
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' => '[email protected]'));

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.

bloggidy
sumber
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.

Orang Mati
sumber
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.

风声 猎猎
sumber
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.

Wang xin
sumber
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.

malam hari
sumber