在 Laravel 的 withCount() 方法中使用 DISTINCT

Posted

技术标签:

【中文标题】在 Laravel 的 withCount() 方法中使用 DISTINCT【英文标题】:Use DISTINCT in Laravel's withCount() method 【发布时间】:2019-11-16 18:30:26 【问题描述】:

使用 Laravel/Lumen eloquent 我可以得到这样的计数关系:

User::withCount('views')->get();

这将使用 SQL

select `users`.*, (select count(*) from `views` where `users`.`id` = `views`.`user_id`) as `views_count` from `users`

并返回所有带有 views_count 属性的模型,太棒了。

但我需要将这些视图计入唯一 IP 列。在这个查询中,我可以像这样简单地将 count(*) 替换为 count(DISTINCT ip):

select `users`.*, (select count(DISTINCT ip) from `views` where `users`.`id` = `views`.`user_id`) as `views_count` from `users`

并在 phpMyAdmin 中返回良好的结果。但是如何在 Laravel eloquent 中实现这一点呢?我找不到任何方法来使用自定义列进行计数。我可以通过这样的查询函数传递数组:

User::withCount(['views' => function ($q)  // what there? ])->get();

但现在我只能通过 where 条件,不能以任何方式使用 Distinct。

我知道我可以先获取模型,然后使用 distinct 和 count 或 groupby 进行 foreach,但我需要保持这个单一的查询,快速而简单。如果我可以在原始 SQL 中轻松实现这一点,那么我也应该在 Laravel 中以某种方式做到这一点。 如果需要,我可以使用一些自定义的 eloquent 方法,因为我将在应用程序的许多地方使用这个唯一计数。

这么短的问题 - 如何结合 withCount 和 Distinct?

PS 我也尝试在模型的关系级别(在 hasMany 上)使用 distinct 或 groupBy,但这不起作用。

【问题讨论】:

【参考方案1】:
User::withCount('views', function($query) 
    $query->select(DB::raw('count(distinct(ip))'));
)->get();

【讨论】:

似乎不适用于 Laravel 8.x【参考方案2】:

Laravel 8.x 解决方案

User::withCount(['views as views_count' => function($query) 
    $query->select(DB::raw('count(distinct(ip))'));
])->get();

注意:不要使用“selectRaw”。

【讨论】:

以上是关于在 Laravel 的 withCount() 方法中使用 DISTINCT的主要内容,如果未能解决你的问题,请参考以下文章

Laravel多个withCount在同一关系上

groupBy withCount 闭包(Laravel 5.3.26)

laravel5.3统计 withCount()方法的使用

Laravel 对多个 withCount 结果求和

Laravel 雄辩用 whereHas 或其他限制 withCount

Laravel WithCount 使用 where