58

How do I accomplish this in Laravel 4.1 Query Builder?

select * from orders where id = (select max(`id`) from orders)

I tried this, working but can't get the eloquent feature.

DB::select(DB::raw('select * from orders where id = (select max(`id`) from orders)'));

Any idea to make it better?

Udhav Sarvaiya
  • 9,380
  • 13
  • 53
  • 64
Shiro
  • 7,344
  • 8
  • 46
  • 80

6 Answers6

68

You should be able to perform a select on the orders table, using a raw WHERE to find the max(id) in a subquery, like this:

 \DB::table('orders')->where('id', \DB::raw("(select max(`id`) from orders)"))->get();

If you want to use Eloquent (for example, so you can convert your response to an object) you will want to use whereRaw, because some functions such as toJSON or toArray will not work without using Eloquent models.

 $order = Order::whereRaw('id = (select max(`id`) from orders)')->get();

That, of course, requires that you have a model that extends Eloquent.

 class Order extends Eloquent {}

As mentioned in the comments, you don't need to use whereRaw, you can do the entire query using the query builder without raw SQL.

 // Using the Query Builder
 \DB::table('orders')->find(\DB::table('orders')->max('id'));

 // Using Eloquent
 $order = Order::find(\DB::table('orders')->max('id'));

(Note that if the id field is not unique, you will only get one row back - this is because find() will only return the first result from the SQL server.).

Robert Pounder
  • 1,490
  • 1
  • 14
  • 29
Tim Groeneveld
  • 8,739
  • 3
  • 44
  • 60
  • it is possible to make it chain `toArray()` ? I got an error if I append with ->toArray(). – Shiro Apr 15 '14 at 03:27
  • @Shiro `toArray()` is a model method of Eloquent, not of DB. You will need to use `whereRaw()` instead. I have updated my answer. – Tim Groeneveld Apr 15 '14 at 05:05
  • thanks for your answer, may I know why u put array(25) for it? – Shiro Apr 15 '14 at 05:49
  • Raw queries are not necessary here, one of the other answers are a better solution. – Erik Berkun-Drevnig Dec 02 '16 at 20:50
  • @ErikBerkun-Drevnig, I have edited my post. I did write this answer so it could be used for any field. Also note that the original answer did not limit the query from returning more then one row. This is (IMHO) an important thing to note. For example, if I wanted to use this query to find user profiles with `max(age)` and `min(age)`. I would not want to limit my results to one row. – Tim Groeneveld Dec 04 '16 at 22:34
56

Just like the docs say

DB::table('orders')->max('id');
Ohgodwhy
  • 49,779
  • 11
  • 80
  • 110
34

For Laravel ^5

Orders::max('id');

I used it is short and best;

Afraz Ahmad
  • 5,193
  • 28
  • 38
19

No need to use sub query, just Try this,Its working fine:

  DB::table('orders')->orderBy('id', 'desc')->pluck('id');

Laravel 5+:

  DB::table('orders')->orderBy('id', 'desc')->value('id');
 
Govind Samrow
  • 9,981
  • 13
  • 53
  • 90
  • 2
    This is a terrible solution. It forces MySQL to look at all your rows, filter them, sort them, and then return the result. Don't do this. Instead opt for something along the lines of `Orders::max('id')` – Edward Oct 29 '18 at 13:11
  • @Edward why would this be terrible? If the table had an index on it (which as an 'id' most likely does) then the DB would handle that fine, as simplest order by. – tristanbailey Jul 25 '21 at 12:12
  • Ran a test and Laravel optimises it to ```select * from `orders` order by `id` desc limit 1``` so not pulling all results as limit is set. If there was no key it would need to do more work. – tristanbailey Jul 25 '21 at 12:22
5

For objects you can nest the queries:

DB::table('orders')->find(DB::table('orders')->max('id'));

So the inside query looks up the max id in the table and then passes that to the find, which gets you back the object.

tristanbailey
  • 4,427
  • 1
  • 26
  • 30
1

You can get the latest record added to the Orders table you can use an eloquent method to retrieve the max aggregate:

$lastOrderId = Order::max('id');

To retrieve a single row by the id column value, use the find method:

$order = Order::find(3);

So combining them, to get the last model added to your table you can use this:

$lastOrder = Order::find(Order::max('id'));
Davide Casiraghi
  • 15,591
  • 9
  • 34
  • 56