Laravel orderByRaw 计数列不存在
Posted
技术标签:
【中文标题】Laravel orderByRaw 计数列不存在【英文标题】:Laravel orderByRaw count column not exits 【发布时间】:2020-09-27 03:10:50 【问题描述】:我有一个 Laravel API,我想在其中提供一个主题标签列表,其中包含使用主题标签的帖子和 cmets 的数量,并按帖子和 cmets 的总数对列表进行排序。
这是我的表格:posts
、comments
、hashtags
、hashtag_post
、comment_hashtag
。此外,我的模型中定义了适当的关系方法。
在阅读了 Laravel 的文档并在网上搜索后,我编写了以下代码:
Hashtag::withCount(['posts', 'comments'])
->orderByRaw('posts_count + comments_count desc')
->paginate(15);
如果我只使用 orderBy
和 posts_count
或 comments_count
单独使用,则查询有效并且我得到一个列表,但是使用上面的代码,我得到这个错误:
Illuminate/Database/QueryException with message 'SQLSTATE[42703]: Undefined column: 7 ERROR: column "posts_count" does not exist ...
我使用 tinker 来查看这些列是否在 SQL 查询中正确定义,这就是我得到的:
select "hashtags".*, (select count(*) from "posts" inner join "hashtag_post" on "posts"."id" = "hashtag_post"."post_id" where "hashtags"."id" = "hashtag_post"."hashtag_id" and "posts"."deleted_at" is null) as "posts_count", (select count(*) from "comments" inner join "comment_hashtag" on "comments"."id" = "comment_hashtag"."comment_id" where "hashtags"."id" = "comment_hashtag"."hashtag_id" and "comments"."deleted_at" is null) as "comments_count" from "hashtags" where "hashtags"."deleted_at" is null order by posts_count + comments_count desc
我已经在网上搜索了有关该错误的信息,但没有发现任何有用的信息。
编辑 1:根据@Ersoy 评论,我将查询更改如下:
Hashtag::selectRaw('Count(posts.id) + Count(comments.id) as total_count')
->withCount(['posts', 'comments'])
->groupBy('hashtags.id')
->orderByRaw('(Count(posts.id) + Count(comments.id)) desc')
->paginate(15);
正如我所料,它没有奏效。它说:
Illuminate/Database/QueryException with message 'SQLSTATE[42P01]: Undefined table: 7 ERROR: missing FROM-clause entry for table "posts"
问题是,likes
和 comments
在另一个问题中,正如我从查询中了解到的那样,是 1-N 关系,而我的关系是 N-M。另外,我认为使用 Count
这样的函数在没有连接的情况下是行不通的。如果我错了,请纠正我。
编辑 2:我的一个朋友给了我这个 SQL 查询,它给出了我想要的结果:
select
h.*,
count(distinct hp.post_id) as posts_count,
count(distinct ch.comment_id) as comments_count
from
hashtags as h
left join hashtag_post as hp on
h.id = hp.hashtag_id
left join posts p on
hp.post_id = p.id
left join comment_hashtag ch on
h.id = ch.hashtag_id
left join comments c on
ch.comment_id = c.id
where
h.deleted_at is null
and p.deleted_at is null
and c.deleted_at is null
group by
h.id
order by
( count(distinct hp.post_id) + count(distinct ch.comment_id) ) desc;
但我不知道如何正确地将其转换为 Eloquent 查询。
【问题讨论】:
这个问题和你的类似——也许答案有帮助? Is it possible to order by the total count of multiple tables? @Ersoy 我编辑了关于您的评论的问题。 如何在order by
子句中的列名周围加上双引号,例如:Hashtag::withCount(['posts', 'comments']) ->orderByRaw('"posts_count" + "comments_count" desc') ->paginate(15);
@GMB 也是同样的错误。
【参考方案1】:
DB::table('hashtags as h')
->leftJoin('hashtag_post as hp', 'h.id', '=' ,'hp.hashtag_id')
->leftJoin('posts as p', 'hp.post_id', '=' ,'p.id')
->leftJoin('comment_hashtag as ch', 'h.id', '=', 'ch.hashtag_id')
->leftJoin('comments as c', 'ch.comment_id', '=' ,'c.id')
->whereNull('h.deleted_at')
->whereNull('p.deleted_at')
->whereNull('c.deleted_at')
->selectRaw("*, count(distinct hp.post_id) + count(distinct ch.comment_id) as total_count")
->groupBy('h.id')
//尝试
->orderByRaw('count(distinct hp.post_id) + count(distinct ch.comment_id) desc')
// 或
->orderByRaw('total_count desc')
->get();
两个 orderByRaw 语句相似,您可以尝试以上任何一种。希望它应该工作。
【讨论】:
感谢您的回答。我会测试它并告诉你结果。 确切的代码不起作用,因为 1. 您选择了所有表中的所有列并按分组抱怨这一点。 2.我需要posts'count和cmets'count分开,只有顺序必须基于它们的总和。但是我稍微修改了代码,它工作了。 是的,我只是忽略了它...我分享了查询结构的雄辩...而不是 * 它应该是h.*, count(distinct hp.post_id) as posts_count, count(distinct ch.comment_id) as comments_count
并且在 orderByRaw 中使用 total_count 你必须在选择中传递它也是。【参考方案2】:
如果 Laravel 版本为 6+,以下代码可以完美运行:
Hashtag::withCount(['posts', 'comments'])
->orderByRaw('posts_count + comments_count desc')
->paginate(15);
但是,我目前使用的是 Laravel 5.7,现在无法升级。因此,我应该使用替代方法来获得所需的结果:
Hashtag::leftJoin('hashtag_post as hp', 'hashtags.id', '=', 'hp.hashtag_id')
->leftJoin('posts as p', 'hp.post_id', '=', 'p.id')
->leftJoin('comment_hashtag as ch', 'hashtags.id', '=', 'ch.hashtag_id')
->leftJoin('comments as c', 'ch.comment_id', '=', 'c.id')
->whereNull('p.deleted_at')
->whereNull('c.deleted_at')
->selectRaw('hashtags.*, count(distinct hp.post_id) as posts_count, count(distinct ch.comment_id) as comments_count')
->groupBy('hashtags.id')
->orderByRaw('count(distinct hp.post_id) + count(distinct ch.comment_id) desc')
->paginate(15)
感谢@tarun-jain
【讨论】:
以上是关于Laravel orderByRaw 计数列不存在的主要内容,如果未能解决你的问题,请参考以下文章
laravel 产品 orderByRaw COALESCE(discount_price, price), discount_price 未定义