Laravel在withCount方法上使用where子句

时间:2016-10-08 09:49:52

标签: php mysql sql laravel eloquent

我正在尝试使用这段代码在laravel的eloquent查询构建器的withCount方法上执行where子句。

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

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

  

SQLSTATE [42S22]:未找到列:1054未知列' upvotes_count'在' where子句' (SQL:选择,(从upvotes选择计数(upvotesupvoteable_id = postsid和{{ 1}}。upvotes = App \ Post)upvoteable_type来自upvotes_count其中posts> 5)

所以从我可以猜到的是,upvotes_count没有被选中,因此没有找到列,但是如果我执行这段代码。

upvotes_count

然后我得到了这个输出。

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

这基本上意味着正在选择upvotes_count,因此我对如何解决这个问题感到很困惑。

(到目前为止我尝试的更多选项在下面给出了相应的错误。)

{
"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
},

错误。

  

SQLSTATE [42S22]:未找到列:1247参考' upvotes_count'不支持(项目列表中的前向引用)(SQL:选择,(从$posts = Post::where('id', $id)->withCount(['upvotes' => function($query) { $query->where('upvotes_count', '>', 5); }])->get(); 选择计数(upvotesupvotes = upvoteable_idpostsidupvotes = App \ Post和upvoteable_type> 5)upvotes_count来自upvotes_count posts = 1)

id

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

错误。

  

SQLSTATE [42S22]:未找到列:1054未知列' upvotes_count'在' where子句' (SQL:select {from $posts = \App\Post::where('id', $id)->with(['upvotes' => function($query) { $query->selectRaw('upvoteable_id AS upvotes_count'); }])->where('upvotes_count', '>', 5)->get(); posts = 1和id> 5)

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

6 个答案:

答案 0 :(得分:11)

您可以使用以下方式获得请求的结果:

virtualenv -p python3 my_env

答案 1 :(得分:1)

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

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

$usedTags = $allTags->filter(function ($value, $key) {
        return $value->articles_count > 0;
    });

答案 2 :(得分:1)

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

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

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

答案 3 :(得分:1)

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

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

答案 4 :(得分:1)

我认为使用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子句(在严格模式下使用),但这可能需要您将表中的每一列都包括在内(由于'ONLY_FULL_GROUP_BY'),如果您再添加另一个则可能会破坏事情列到您的表中,并且可能仍然无法正常工作,因为我认为您需要在groupBy中包括“ upvotes_count”,而且这似乎是一个非分组字段。

答案 5 :(得分:0)

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

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

现在,您可以在刀片中完成

$posts->upvotes_count