Laravel orderByRaw 计数列不存在

Posted

技术标签:

【中文标题】Laravel orderByRaw 计数列不存在【英文标题】:Laravel orderByRaw count column not exits 【发布时间】:2020-09-27 03:10:50 【问题描述】:

我有一个 Laravel API,我想在其中提供一个主题标签列表,其中包含使用主题标签的帖子和 cmets 的数量,并按帖子和 cmets 的总数对列表进行排序。

这是我的表格:postscommentshashtagshashtag_postcomment_hashtag。此外,我的模型中定义了适当的关系方法。

在阅读了 Laravel 的文档并在网上搜索后,我编写了以下代码:

Hashtag::withCount(['posts', 'comments'])
    ->orderByRaw('posts_count + comments_count desc')
    ->paginate(15);

如果我只使用 orderByposts_countcomments_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"

问题是,likescomments 在另一个问题中,正如我从查询中了解到的那样,是 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()

Laravel 迁移显示现有列的列不存在

laravel 产品 orderByRaw COALESCE(discount_price, price), discount_price 未定义

laravel框架orderBy问题

Laravel 4中的列不明确错误

使用 laravel 急切加载选择特定列不起作用