Laravel Query Builder where max id - php

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?

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

Just like the docs say
DB::table('orders')->max('id');

For Laravel ^5
Orders::max('id');
I used it is short and best;

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');

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.

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'));

Related

Insert from select in laravel using eloquent

I am using laravel 8. I want to insert multiple rows by selecting from one table to another. I am using DB::statement() but now want to do it using eloquent. Here is my sample code:
DB::statement("insert into bank_information (user_id, bank_id, account_name,account_number)
select applicant_id,bank_id,account_name,account_number from applicant_bank_information
where erec_applicant_bank_information.applicant_id =".$applicant_id);
How can I do it using single eloquent command ? Also, Is there any other smarter/faster way for it in laravel ??
I do not know of a Eloquent way for this, but after Laravel 5.7.17 we have a new method in the query builder insertUsing(). Unfortunately this is not mentioned in the official documentation.
The query builder code will be something like this:
$select = DB::table('applicant_bank_information as abi')
->select('applicant_id','bank_id','account_name','account_number')
->where('abi.applicant_id', $applicant_id);
$rows_inserted = DB::table('bank_information')
->insertUsing(['user_id','bank_id', 'account_name','account_number'], $select);
Tested and working. Keep in mind that you do not run the select request with ->get().

Using Laravel's query builder or Eloquent to inner join a table with a temporary one

I have a rather complex query that I'm going to simplify it for making it easier to read:
SELECT `temp_table`.field1, `temp_table`.field2 FROM
(A TEMPORARY TABLE MADE OUT OF A SELECTION QUERY) AS temp_table
INNER JOIN table ON temp_table.field1 = table.id
WHERE table.some_field = 'something'
I am currently using a RAW query for this, but now I want to rewrite it using either Query Builder or Eloquent ORM in Laravel. I am new to Laravel. So, any idea or help is appreciated.
try using fromSub
DB::query()->fromSub(function ($query) {
$query->selectRaw('your query to get the temp_table');
}, 'temp_table')->join('table','table.id','=','temp_table.field1')
->where('table.some_field','something');
the method 'fromSub' take a string as second parameter, it is 'as' in sql, so you can use it to name the temp table ....

Id Column Overwritten by Join

Using Laravel 4.2 & MySQL.
I have an applications table with an id and a fit_score_id column, and a fit_scores table with an id column. It's a basic "belongs to" relationship.
The following code:
$query = Application::join('fit_scores', 'applications.fit_score_id', '=', 'fit_scores.id');
$collection = $query->get();
...produces a collection of Application models with the id property set to the value of the fit_score_id. What am I doing to cause this?
I should note that it is necessary to do this join rather than simply using eloquent relations, because I'm going to want to order the results by a column on the fit_scores table. I don't believe this is possible using Eloquent without an explicit join.
The best way to solve this is by chaining the join method to a select method as following:
Application::select('*', \DB::raw("applications.id as appid"))
->join('fit_scores', 'applications.fit_score_id', '=', 'fit_scores.id')
->get();
Explained: The solution simply suggest that instead of thinking to prevent the behavior of overwriting the first id with the joined id, we can hook into the primary selection query (before joining) and change the label of the id column into something else (in this case 'appid'). By doing so, we end up with both the id of the parent table being labeled 'appid' and the id of the joined table being labeled 'id' again while they lives together on the final result.
I was able to find a possible solution using this answer:
Laravel 4 - JOIN - Same column name
Basically, since Laravel does not automatically prefix column names with table_name. for joined tables, we need to manually work around it by aliasing any conflicting column names in joins. Adding this select statement to my query did it:
->select(DB::raw("applications.*, fit_scores.*, applications.id as id"))
It depends on what you need but probably you can achieve it using eager loading. In case you need to mix joins and eager loading check this out. http://www.jmilan.net/posts/eager-loading-joins-in-laravel

Laravel query builder, use custom select when calling count()

I have three tables, one defining a many to many relationship between the other two.
table : collections
table : collection_question
table : questions
I am running this query to return the number of questions a collection has
$results = DB::table('collections')
->select(array(
DB::raw('count(collection_question.question_id) as question_count'),
'name',
'description'
))->leftJoin(
'collection_question',
'collections.id',
'=',
'collection_question.collection_id'
)->where('question_count', '>', 1)
->orderBy('question_count', 'asc')
->get();
This works fine as the select query is not tampered with by the query builder.
When I swap out get() for count() however the query builder replaces my select clause with select count(*) as aggregate which is understandable, however I loose the binding to question_count in the process and a SQL exception is thrown.
I've looked through the source code for Illuminate\Database\Query\Builder to try and find a solution but other than manually executing the raw query with a custom count(*) alongside my other select clauses I'm at a bit of a loss.
Can anyone spot a solution to this?
Instead of calling count() on a Builder object, I've resorted to creating my own count expression in addition to any other select clauses on the query rather than replacing them.
// This is in a class that uses Illuminate\Database\Query\Expression the clone
// isn't necessary in most instances but for my case I needed to take a snapshot
// of the query in its current state and then manipulate it further.
$query = clone($query);
$query->addSelect(new Expression("count(*) as aggregate"));
$count = (int) $query->first()->aggregate;

Laravel 4: Order query relation randomly and limited

I'm using Laravel 4 and I'm running into an issue with eloquent.
I've got it set up to grab the category, get the products and limit it to 2. However I'm having trouble getting the random element. I need it to select from two random products, rather than the newest/latest.
$products = Category::find($id)->products->take($limit);
$products->load('imageThumb');
return $products;
I'd like to keep the solution eloquent based, but if that's not an option I'll switch to a raw query code.
Thanks!
$products = Category::find($id)->products()->orderBy(DB::raw('RAND()'))->take($limit)->get();
(sorry forgot the ->get() in my original answer)
How's big is the table? If it is not too big you can use MySQL ORDER BY RAND()
http://davidwalsh.name/mysql-random
Eloquent something like:
->orderBy(DB::raw('RAND()'))

Categories