ChatGPT解决这个技术问题 Extra ChatGPT

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.

Also see stackoverflow.com/questions/33321447/… How to sort a an existing relationship (hasMany)
This is for anyone asking and answering about Laravel. Remember that it is important to specify which Laravel version you are talking about. Generally version 4 and 5 have differences and older versions too.

M
ManojKiran Appathurai

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.


For Laravel 4 this should be orderBy, not order_by
When you use ORM, this is a correct way: User::orderby('created_at', 'desc')->first();
Laravel 5.x = orderBy('created_at', 'desc')
Why are you using created_at column? Much faster to use primary key ID. Laravel 5.x Files::orderBy(id', 'desc')->first(); Order by date works longer because date is string and most likely not indexed. While primary key is indexed and works super fast. Even if created_at indexed, it is indexed string and not INT in case of primary. Index string has less performance.
@KorbenDallas comment should be the answer because sometimes orderBy('created_at', 'desc') does not give you the last row. Example: 3 rows can have exactly the same TIMESTAMP value and with orderBy('created_at', 'desc') you will get the first of the 3(which is not necessarily the last row)
N
Nick

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.


Note that this method use the auto-generated created_at column ($timestamps = true) in the Model, but can be disabled at wish so you would have an error if undefined
I'm using Laravel 5.7 and trying to do this on a Model still retrieves all the records for me.
Note that if you have multiple records added within the same second, the created_at time will be the same for these records and therefore the record returned by latest() may not be the record you expect it to be.
Note that you don't need a 'created_at' column. You can specify from what column you want the latest. For example: Model::latest('dateColumn')->first();
This may fail to get the actual last row if two row are inserted within 1 sec (actually caused problems in unit testing).
T
Thelambofgoat

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 an 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.


This throws an error, my column "video_title" is of type STRING, Attempt to read property "video_title" on bool it's also 2021 (and it might be such an old answer) and im using Laravel 8, thanks!
in case of realtionship $this->posts()->latest()->first() in the user model for instance.
H
Haseena P A

To get last record details

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

To get last record id

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


If you use the first option, you might make your PHP die, trying to allocate information in the available memory it has. It basically fetches the entire table, creates an instance for each record, and stores it in the RAM. Then, it only gets the last record, but only if PHP has not died yet. The second method is the efficient one since it gets only the necessary information from the DB.
M
Maik Lowrey

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.


m
mdamia

Laravel collections has method last

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

This is the best way to do it.


Just wanted to point out that the all() method actually loads all of the items. This won't work on a table with millions of records.
In addition to Steven Jeffries comment, I would like to point out that calling last() returns a single Eloquent instance and not a Collection, and calling pluck() on that is equal to calling Model::all()->pluck('name'), therefore returning the name attribute of all the rows in the table
This method is worse actually. You are fetching last raw using PHP execution instead of doing it as DB level. What if table has millions of raw, then you know how much inefficient it can be?
This is the best way to do it. - No! Never has been, never will. You'd be loading all rows instead of just the one you need.
Love this bcz this not required any timestamp column if your table doesn't have created_at or any similiar column
t
tiaguinhow

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.


What if id is uuid ?
@BariqDharmawan you can do Model::latest('uuid')->first() or whatever field you want.
Wow IDK latest() method work with uuid. Bcz I think it's a fully random string and can't be order by asc. Thank you
U
Udhav Sarvaiya

Try this :

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

This will return multiple rows. He needs a single row. first() will help him with orderBy() clause.
This may fail to get the actual last row if two row are inserted within 1 sec (actually caused problems in unit testing).
On a large table this will cause out of memory exception because as @TahirAfridi mentioned this will load all rows into memory.
R
Rayhanur Rahaman Rubel

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.


@Mohammad The correct way is: Model::orderBy('id', 'desc')->first(); Here 'id' is the primary key (auto increment) of the table.
佚名

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

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

Don't use it. This is a very bad practice there is a scope latest() it provides direct access to last inserted row.
T
Towelie

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;


Also works for me in Laravel 5.8, just posted the answer before seeing yours
A little explanation on how laravel does this behind the scene and why this is dangerous for large data set, get() method will fetch everything from your_table and generate a Collection and last() method will get the last item from that collection. So you will already have all of the data from the table loaded on your memory(bad). You should just use ` DB::table('items')->latest()->first();` behind the scene it perform ` orderBy($column, 'desc')` and fetch the first record.
D
Dazzle

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


E
Eduardo

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:

The last row ever created on my table 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();

风声猎猎

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.


d
doox911

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


b
bloggidy

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' => 'example@gmail.com'));

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.


T
The Billionaire Guy

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.


m
mangonights

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.


w
wang xin

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.