如何在 Laravel 5.1 中编写这个(左连接、子查询)?
Posted
技术标签:
【中文标题】如何在 Laravel 5.1 中编写这个(左连接、子查询)?【英文标题】:How to write this (left join, subquery ) in Laravel 5.1? 【发布时间】:2015-10-19 01:50:39 【问题描述】:如何在 Laravel 5.1 中编写此查询:
SELECT p.id, p.title, p.created_at, p.updated_at, u.name, COALESCE(c.comments_count, 0) AS comments_count, COALESCE(pl.status_sum, 0) AS status_sum
FROM posts p
LEFT OUTER JOIN users u ON u.id = p.user_id
LEFT OUTER JOIN (
SELECT pl.post_id, SUM(pl.status) AS status_sum
FROM postslikes pl
GROUP BY pl.post_id
) pl ON pl.post_id = p.id
LEFT OUTER JOIN (
SELECT c.post_id, COUNT(*) as comments_count
FROM comments c
GROUP BY c.post_id
) c ON c.post_id = p.id ORDER BY comments_count DESC
我需要它来进行分页。我可以毫无问题地执行这个查询,但是手动分页器总是给出相同的结果: http://laravel.com/docs/5.1/pagination#manually-creating-a-paginator 和这里一样的问题:http://laravel.io/forum/07-22-2015-laravel-51-manual-pagination-not-working-as-expected
我的尝试没有成功:
DB::table( 'posts' )
->select( 'posts.id', 'posts.title', 'posts.created_at', 'posts.updated_at', 'users.name', DB::raw( 'COALESCE( comments.body, 0 ), COALESCE( postslikes.status, 0 )' ) )
->leftJoin( 'users', 'users.id', '=', 'posts.user_id' )
->leftJoin( DB::raw( 'SELECT postslikes.post_id, SUM( postslikes.status ) FROM postslikes GROUP BY postslikes.post_id' ), function( $join )
$join->on( 'postslikes.post_id', '=', 'post.id' );
)
->leftJoin( DB::raw( 'SELECT comments.post_id, COUNT(*) FROM comments GROUP BY comments.post_id' ), function( $join )
$join->on( 'comments.post_id', '=', 'post.id' );
)
->get();
我认为问题在于 cmets_count 和 status_sum? 谢谢!
【问题讨论】:
嘿,@baker!我下面的回答对你有帮助吗?如果是这样,请考虑接受/支持它。这样做可以帮助其他人寻求类似问题的解决方案。 【参考方案1】:要在 Laravel 的查询构建器中使用子查询,您应该将其添加到连接中,如下所示:
->leftJoin(DB::raw("(SELECT [...]) AS p"), 'p.post_id', '=', 'posts.id')
最好为计算字段创建别名,就像您在原始查询中所做的那样:
COUNT(*) AS count
尽管发生了这些变化,除非我错了,否则您可以从简化查询开始。以这种方式删除子查询:
SELECT
p.id,
p.title,
p.created_at,
p.updated_at,
u.name,
COUNT(c.id) AS comments_count,
COALESCE(SUM(pl.status), 0) AS status_sum
FROM
posts p
LEFT OUTER JOIN
users u
ON
u.id = p.user_id
LEFT OUTER JOIN
postslikes pl
ON
pl.post_id = p.id
LEFT OUTER JOIN
comments c
ON
c.post_id = p.id
ORDER BY
comments_count DESC
GROUP BY
p.id
然后,通过这个新查询,您可以使用 Laravel 来构建它:
DB::table('posts')
->select([
'posts.id',
'posts.title',
'posts.created_at',
'posts.updated_at',
'users.name',
DB::raw('COUNT(comments.id) AS comments_count'),
DB::raw('COALESCE(SUM(postslikes.status), 0) AS status_sum'),
])
->leftJoin('users', 'users.id', '=', 'posts.user_id')
->leftJoin('comments', 'comments.post_id', '=', 'posts.id')
->leftJoin('postslikes', 'postslikes.post_id', '=', 'posts.id')
->orderBy('comments_count', 'DESC')
->groupBy('posts.id')
->get();
请注意,我假设您的 comments
表中有一个名为 id
的列作为主键。
【讨论】:
以上是关于如何在 Laravel 5.1 中编写这个(左连接、子查询)?的主要内容,如果未能解决你的问题,请参考以下文章