Laravel 在 withCount 方法上使用 where 子句

问题描述 投票:0回答:6

我正在尝试使用这段代码对 laravel 的雄辩查询生成器的 withCount 方法执行 where 子句。

$posts = Post::withCount('upvotes')->where('upvotes_count', '>', 5)->get();

这段代码给了我这个错误。

SQLSTATE[42S22]:未找到列:1054“where 子句”中的未知列“upvotes_count”(SQL:select ,(select count() from

upvotes
where
upvotes
.
upvoteable_id
=
posts
id
upvotes
upvoteable_type
= App\Post) 为来自
upvotes_count
posts
,其中
upvotes_count
> 5)

所以据我猜测,upvotes_count 未被选择,因此未找到该列,但是如果我执行这段代码。

$posts = Post::withCount('upvotes')->get();

然后我得到这个输出。

{
"id": 1,
"user_id": 15,
"title": "Voluptatum voluptas sint delectus unde amet quis.",
"created_at": "2016-10-07 13:47:48",
"updated_at": "2016-10-07 13:47:48",
"upvotes_count": 7
},
{
"id": 2,
"user_id": 2,
"title": "Molestiae in labore qui atque.",
"created_at": "2016-10-07 13:47:48",
"updated_at": "2016-10-07 13:47:48",
"upvotes_count": 2
},

这基本上意味着 upvotes_count 被选中,因此我真的很困惑如何解决这个问题。

(下面给出了我迄今为止尝试过的更多选项以及与之相关的相应错误。)

$posts = Post::where('id', $id)->withCount(['upvotes' => function($query) {
        $query->where('upvotes_count', '>', 5);
    }])->get();

错误。

SQLSTATE[42S22]:未找到列:1247 不支持引用“upvotes_count”(项目列表中的前向引用)(SQL:select ,(从 upvotes

 选择计数(
),其中
upvotes
.
upvoteable_id
=
posts
.
id
upvotes
.
upvoteable_type
= App\Post 和
upvotes_count
> 5) 作为来自
upvotes_count
posts
,其中
id
= 1)

代码。

$posts = Post::where('id', $id)->with(['upvotes' => function($query) {
        $query->select('upvoteable_id AS upvotes_count');
    }])->where('upvotes_count', '>', 5)->get();

$posts = \App\Post::where('id', $id)->with(['upvotes' => function($query) {
        $query->selectRaw('upvoteable_id AS upvotes_count');
    }])->where('upvotes_count', '>', 5)->get();

错误。

SQLSTATE[42S22]:未找到列:1054“where 子句”中的未知列“upvotes_count”(SQL:从

posts
选择 *,其中
id
= 1 且
upvotes_count
> 5)


我只想在与父模型有关系的 count() 方法上使用 where 子句。

php laravel eloquent
6个回答
45
投票

您可以通过使用以下方式达到所要求的结果:

$posts = Post::withCount('upvotes')
         ->having('upvotes_count', '>', 5)
         ->get();

35
投票

另一个好方法来做到这一点 我们可以单独过滤它,甚至为该列名称分配一个别名

$posts = Post::withCount([
    'upvotes', 
    'upvotes as upvotes_count' => function ($query) {
        $query->where('upvotes_count', '>', 5);
    }])
    ->get();

现在在 Blade 中你可以做到

$posts->upvotes_count

10
投票

我不确定这是否在你提出问题后实施,但你现在可以这样做

$posts = Post::has('upvotes','>',5)->get();

7
投票

我认为使用 has() 是最好的解决方案:

Post::has('upvotes','>',5)->withCount('upvotes')->get()

您还可以使用过滤器:

Post::withCount('upvotes')->get()->filter(function($post) { return $post->upvotes_count > 5; })

您还可以在 config/database.php 中禁用严格模式(可能不是一个好主意)

'strict' => false,

Post::withCount('upvotes')->having('upvotes_count','>',5)->get()

您还可以尝试添加一个 groupBy 子句(在严格模式下使用having),但这可能需要您包含表中的每一列(由于“ONLY_FULL_GROUP_BY”),如果您向其中添加另一列,这可能会破坏事情你的表,可能无论如何都不起作用,因为我认为你需要在 groupBy 中包含“upvotes_count”,它似乎是一个非分组字段。


3
投票

如果您需要仅选择计数器大于或等于1的行,您可以尝试以下代码:

$posts = Post::withCount('upvotes')
             ->havingRaw('upvotes_count')
             ->get();

我不知道这是否是最好的解决方案,但它是一个替代方案。另一种选择是获取帖子并使用上面评论中提到的数组过滤器。


1
投票

我遇到了同样的问题,并尝试了与你相同的方法。 我猜测有一种方法可以复制 withCounts 调用生成的 SQL,但添加一种方法使 xxx_counts 可用于 where 子句,但我只是过滤了结果集合。

$allTags = Tag::withCount('articles')->get();

$usedTags = $allTags->filter(function ($value, $key) {
        return $value->articles_count > 0;
    });
© www.soinside.com 2019 - 2024. All rights reserved.