【问题标题】:Laravel using where clause on a withCount methodLaravel 在 withCount 方法上使用 where 子句
【发布时间】:2017-02-17 06:19:40
【问题描述】:

我正在尝试使用这段代码对 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.@ 987654324@ = posts.idupvotes.upvoteable_type = App\Post) as upvotes_count from posts where 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 ,(select count() from upvotes where @987654336 @.upvoteable_id = posts.idupvotes.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:select * from posts where id = 1 和 upvotes_count > 5)


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

【问题讨论】:

    标签: php mysql sql laravel eloquent


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

      我认为使用 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”,它似乎是一个非分组字段。

      【讨论】:

      • 谢谢,这很好用。由于 has() 函数,它允许一个条件,而 withCount 允许我使用 orderBy。再次,非常感谢。
      【解决方案3】:

      另一种好方法 我们可以单独过滤,甚至为该列名分配别名

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

      现在你可以在刀片中做

      $posts->upvotes_count
      

      【讨论】:

      • 感谢您提供这个带有自定义查询和计数别名的示例。这允许我们在同一个相关表上添加多个计数,但使用不同的自定义查询。
      • 很高兴它有帮助。
      • 其实这是关系的正确方式
      • 'upvotes as upvotes_count' 还不够吗,我们真的需要将数组中的'upvotes' 传递给withCount(...)method 吗?
      • 哇,太棒了。谢谢。
      【解决方案4】:

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

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

      【讨论】:

        【解决方案5】:

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

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

        【讨论】:

        • 我仍然收到错误:upvotes_count 列不存在。我不确定这是如何工作的,因为根据我的研究,它看起来像是在 select 语句之前执行了有子句,因此别名 upvotes_count 尚未定义。我正在使用 Postgres。这仅适用于 MySQL 吗?除了必须执行havingRaw 以再次手动获取计数之外,还有其他方法吗?
        • @Stetzon withCount('upvotes') 应该添加upvotes_count,所以你应该添加这个,或者如果你仍然有这个问题,给我发送查询,我会检查它。
        • @Stetzon 请记住,您不能在聚合列上使用 where 子句,但是您可以使用子句,因此请确保您没有在 where 那里使用。
        • 我还有一个错误,MySQL 中不存在该列。
        • 此处相同,“未定义列:7 错误:列“users_count”不存在”。问题是,“have()”正在产生错误,“orderBy”有效。
        【解决方案6】:

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

        $allTags = Tag::withCount('articles')->get();
        
        $usedTags = $allTags->filter(function ($value, $key) {
                return $value->articles_count > 0;
            });
        

        【讨论】:

        • 已经很长一段时间了,随着我对 sql 的了解更多,您不能在聚合函数上执行 where 子句,因此 upvotes_count 列未找到,因为它已聚合且未选中。但上述问题可以使用一些高级查询并将它们组合在一起来解决。
        猜你喜欢
        • 2020-01-30
        • 2020-05-29
        • 2019-11-16
        • 2017-08-05
        • 2015-05-11
        • 2019-09-08
        • 2019-03-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多