Carlos Suñol
Carlos Suñol

Reputation: 2803

Select Last Row in the Table

I would like to retrieve the last file inserted into my table. I know that the method first() exists and provides you with the first file in the table but I don't know how to get the last insert.

Upvotes: 274

Views: 683525

Answers (24)

mdamia
mdamia

Reputation: 4557

Laravel collections has method last

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

Upvotes: 13

Viva Hadi
Viva Hadi

Reputation: 1

Model::query()->latest()->get(); model::query()->latest()->take(10)->get();

Upvotes: 0

blakroku
blakroku

Reputation: 551

The user has many files

A file belongs to a user

/* Now you can get the last inserted file */

$file = auth()->user()->file->last();

Upvotes: 0

Towelie
Towelie

Reputation: 79

Edit : The best way to do it as @Anuj said :

DB::table('your_table')->latest('your_field')->first() will only fetch the last record (as opposed to the above example where we fetch all entries in a collection then retrieve the latest item for this collection)

==================================================

Another fancy way to do it in Laravel 6.x (Unsure but must work for 5.x aswell) :

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

You can access fields too :

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

Upvotes: 4

Luis Milanese
Luis Milanese

Reputation: 1286

You never mentioned whether you are using Eloquent, Laravel's default ORM or not. In case you are, let's say you want to get the latest entry of a User table, by created_at, you probably could do as follow:

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

First it orders users by created_at field, descendingly, and then it takes the first record of the result.

That will return you an instance of the User object, not a collection. Of course, to make use of this alternative, you got to have a User model, extending Eloquent class. This may sound a bit confusing, but it's really easy to get started and ORM can be really helpful.

For more information, check out the official documentation which is pretty rich and well detailed.

Upvotes: 98

Pascal Tovohery
Pascal Tovohery

Reputation: 986

With pdo we can get the last inserted id in the docs PDO lastInserted

Process

use Illuminate\Support\Facades\DB;
// ...
$pdo = DB::getPdo();
$id = $pdo->lastInsertId();
echo $id;

Upvotes: 0

rahali badr eddine
rahali badr eddine

Reputation: 77

you can use this functions using eloquent :

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

Upvotes: -2

Aditya Jodhani
Aditya Jodhani

Reputation: 41

You just need to retrive data and reverse them you will get your desire record let i explain code for laravel 9

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

and if you want no. of x last result

 return DB::table('files')->orderBy('upload_time', 'desc')->limit(x)->get();

Upvotes: 2

Maik Lowrey
Maik Lowrey

Reputation: 17594

Many answers and some where I don't quite agree. So I will summarise again with my comments.

In case you have just created a new object. By default, when you create a new object, Laravel returns the new object.

$lastCreatedModel = $model->create($dataArray); 

dd($lastCreatedModel); // will output the new output
echo $lastCreatedModel->key; // will output the value from the last created Object

Then there is the approach to combine the methods all() with (last()and first()) without a condition.

Very bad! Don't do that!

Model::get()->last();` // the most recent entry
Model::all()->last();` // the most recent entry

Model::get()->first();` // the oldest entry
Model::all()->first();` // the oldest entry

Which is basically the wrong approach! You get() all() the records, and in some cases that can be 200,000 or more, and then pick out just one row. Not good! Imagine your site is getting traffic from Facebook and then a query like that. In one month that would probably mean the CO² emissions of a city like Paris in a year. Because the servers have to work unnecessarily hard. So forget this approach and if you find it in your code, replace it/rewrite it. Maybe you don't notice it with 100 data sets but with 1000 and more it can be noticeable.

Very good would be:

Model::orderBy('id', 'desc')->last(); // the most recent record
Model::latest('id')->first(); // the most recent record
Model::latest('id')->limit(1)->get(); // the most recent record
Model::orderBy('id', 'desc')->limit(1)->get(); // the most recent entry
Model::orderBy('id', 'desc')->first(); // the most recent entry

Model::orderBy('id', 'asc')->first(); // the oldest entry
Model::orderBy('id', 'asc')->limit(1)->get(); // the oldest entry
Model::orderBy('id', 'asc')->first(); // the oldest entry

If orderBy is used in this context, the primarykey should always be used as a basis and not create_at.

Upvotes: 44

Eduardo
Eduardo

Reputation: 294

Honestly this was SO frustrating I almost had to go through the entire collection of answers here to find out that most of them weren't doing what I wanted. In fact I only wanted to display to the browser the following:

  1. The last row ever created on my table
  2. Just 1 resource

I wasn't looking to ordering a set of resources and order that list through in a descending fashion, the below line of code was what worked for me on a Laravel 8 project.

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

Upvotes: 5

doox911
doox911

Reputation: 529

For laravel 8:

Model::orderBy('id', 'desc')->withTrashed()->take(1)->first()->id

The resulting sql query:

Model::orderBy('id', 'desc')->withTrashed()->take(1)->toSql()

select * from "timetables" order by "id" desc limit 1

Upvotes: 4

Don't use Model::latest()->first(); because if your collection has multiple rows created at the same timestamp (this will happen when you use database transaction DB::beginTransaction(); and DB::commit()) then the first row of the collection will be returned and obviously this will not be the last row.

Suppose row with id 11, 12, 13 are created using transaction then all of them will have the same timestamp so what you will get by Model::latest()->first(); is the row with id: 11.

Upvotes: 9

mangonights
mangonights

Reputation: 989

be aware that last(), latest() are not deterministic if you are looking for a sequential or event/ordered record. The last/recent records can have the exact same created_at timestamp, and which you get back is not deterministic. So do orderBy(id|foo)->first(). Other ideas/suggestions on how to be deterministic are welcome.

Upvotes: 1

Haseena P A
Haseena P A

Reputation: 17416

To get last record details

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

To get last record id

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

Upvotes: 65

tiaguinhow
tiaguinhow

Reputation: 255

You can use the latest scope provided by Laravel with the field you would like to filter, let's say it'll be ordered by ID, then:

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

So in this way, you can avoid ordering by created_at field by default at Laravel.

Upvotes: 15

Dazzle
Dazzle

Reputation: 3083

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

Upvotes: 3

风声猎猎
风声猎猎

Reputation: 1201

Use Model::where('user_id', $user_id)->latest()->get()->first(); it will return only one record, if not find, it will return null. Hope this will help.

Upvotes: 3

Joachim Isaksson
Joachim Isaksson

Reputation: 181077

You'll need to order by the same field you're ordering by now, but descending. As an example, if you have a time stamp when the upload was done called upload_time, you'd do something like this;

For Pre-Laravel 4

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

For Laravel 4 and onwards

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

For Laravel 5.7 and onwards

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

This will order the rows in the files table by upload time, descending order, and take the first one. This will be the latest uploaded file.

Upvotes: 345

Mark-Hero
Mark-Hero

Reputation: 205

Try this :

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

Upvotes: 11

wang xin
wang xin

Reputation: 3

If the table has date field, this(User::orderBy('created_at', 'desc')->first();) is the best solution, I think. But there is no date field, Model ::orderBy('id', 'desc')->first()->id; is the best solution, I am sure.

Upvotes: 0

user7889367
user7889367

Reputation:

To get the last record details, use the code below:

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

Upvotes: 6

Nick
Nick

Reputation: 2431

Use the latest scope provided by Laravel out of the box.

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

That way you're not retrieving all the records. A nicer shortcut to orderBy.

Upvotes: 243

The Billionaire Guy
The Billionaire Guy

Reputation: 3552

Somehow all the above doesn't seem to work for me in laravel 5.3, so i solved my own problem using:

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

hope am able to bail someone out.

Upvotes: 1

bloggidy
bloggidy

Reputation: 19

If you are looking for the actual row that you just inserted with Laravel 3 and 4 when you perform a save or create action on a new model like:

$user->save();

-or-

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

then the inserted model instance will be returned and can be used for further action such as redirecting to the profile page of the user just created.

Looking for the last inserted record works on low volume system will work almost all of the time but if you ever have to inserts go in at the same time you can end up querying to find the wrong record. This can really become a problem in a transactional system where multiple tables need updated.

Upvotes: 1

Related Questions