我正在尝试链接4个表,并添加一个自定义字段,通过使用laravel计算一些相关表的ID来计算。 我在SQL中有这个可以做我想要的,但我认为它可以提高效率:
DB::select('SELECT
posts.*,
users.id AS users_id, users.email,users.username,
GROUP_CONCAT(tags.tag ORDER BY posts_tags.id) AS tags,
COUNT(DISTINCT comments.id) AS NumComments,
COUNT(DISTINCT vote.id) AS NumVotes
FROM
posts
LEFT JOIN comments ON comments.posts_id = posts.id
LEFT JOIN users ON users.id = posts.author_id
LEFT JOIN vote ON vote.posts_id = posts.id
LEFT JOIN posts_tags ON posts_tags.posts_id = posts.id
LEFT JOIN tags ON tags.id = posts_tags.tags_id
GROUP BY
posts.id,
posts.post_title');
我尝试使用eloquent实现它:
$trending=Posts::with(array('comments' => function($query)
{
$query->select(DB::raw('COUNT(DISTINCT comments.id) AS NumComments'));
},'user','vote','tags'))->get();
但是,NumComments值未显示在查询结果中。 任何线索怎么回事呢?
答案 0 :(得分:11)
您无法使用with
执行此操作,因为它会执行单独的查询。
您需要的是简单的join
。只需将您拥有的查询翻译为:
Posts::join('comments as c', 'posts.id', '=', 'c.id')
->selectRaw('posts.*, count(distinct c.id) as numComments')
->groupBy('posts.id', 'posts.post_title')
->with('user', 'vote', 'tags')
->get();
然后集合中的每个帖子都有count属性:
$post->numComments;
虽然第一种解决方案在性能方面更好(除非你有大数据,否则可能不会引人注意)
// helper relation
public function commentsCount()
{
return $this->hasOne('Comment')->selectRaw('posts_id, count(*) as aggregate')->groupBy('posts_id');
}
// accessor for convenience
public function getCommentsCountAttribute()
{
// if relation not loaded already, let's load it now
if ( ! array_key_exists('commentsCount', $this->relations)) $this->load('commentsCount');
return $this->getRelation('commentsCount')->aggregate;
}
这将允许您这样做:
$posts = Posts::with('commentsCount', 'tags', ....)->get();
// then each post:
$post->commentsCount;
对于很多很多关系:
public function tagsCount()
{
return $this->belongsToMany('Tag')->selectRaw('count(tags.id) as aggregate')->groupBy('pivot_posts_id');
}
public function getTagsCountAttribute()
{
if ( ! array_key_exists('tagsCount', $this->relations)) $this->load('tagsCount');
$related = $this->getRelation('tagsCount')->first();
return ($related) ? $related->aggregate : 0;
}
更多这样的例子可以在http://softonsofa.com/tweaking-eloquent-relations-how-to-get-hasmany-relation-count-efficiently/
找到答案 1 :(得分:0)
从laravel 5.3开始,您可以执行此操作
withCount('comments','tags');
并这样称呼
$post->comments_count;