Reputation: 2552
I am trying to get my users (authors actually, there will be maximum of 5-6 authors) with their one last post to show in a sidebar in the homepage. Since they will be listed in the homepage I am trying to reduce the amount of sql queries due to performance issues. I have tried;
$users=User::with(array('posts'=>function($query){
$query->take(1);
}))->get();
However it gets only one post in total, not one for every user. And my sql knowledge is limited.
How can I solve my poblem using Eloquent ORM, Query Builder or raw sql query?
Upvotes: 3
Views: 1330
Reputation: 18665
A solution is to define a hasOne
relationship on the User
model ordering by the posts created_at
column.
public function lastPost()
{
return $this->hasOne('Post')->orderBy('created_at', 'desc');
}
Then your query would be as such.
$users = User::with('lastPost')->get();
To limit the columns you can constrain the query either at the relationship level:
return $this->hasOne('Post')->select('id', 'user_id', 'title', 'created_at')->orderBy('created_at', 'desc');
Or when you use the with
method:
$users = User::with(['lastPost' => function($query)
{
$query->select('id', 'user_id', 'title', 'created_at');
})->get();
Note that you need the user_id and created_at columns as well, as they're required for the WHERE
and ORDER BY
clauses in the query.
Upvotes: 4
Reputation: 1270713
The general SQL way to do this is:
select p.*
from posts p join
(select p.authorid, max(created_at) as maxdate
from posts p
group by p.authorid
) psum
on p.authorid = psum.authorid and p.created_at = psum.maxdate
This assumes that there is are no duplicates.
Depending on the database you are using, there are definitely other ways to write this query. That version is standard SQL.
Upvotes: 1