Laravel Eloquent - distinct() 和 count() 不能一起正常工作
Posted
技术标签:
【中文标题】Laravel Eloquent - distinct() 和 count() 不能一起正常工作【英文标题】:Laravel Eloquent - distinct() and count() not working properly together 【发布时间】:2015-04-23 11:23:36 【问题描述】:所以我试图在查询中获取不同 pid 的数量,但返回的值是错误的。
这是我尝试做的:
$ad->getcodes()->groupby('pid')->distinct()->count()
什么返回值“2”,而它应该返回的值应该是“1”。
作为一种解决方法,我正在这样做:
count($ad->getcodes()->groupby('pid')->distinct()->get())
什么工作正常并返回“1”
是否有任何规则使 count 和 distinct 不能在同一个查询上?我发现解决方法有点“重”,我想让原始查询工作:(
【问题讨论】:
您在数据库的示例表中有什么?你想达到什么目标?现在您可能应该在pid
列中获得不同值的数量,因此如果您的表中有 2 条记录 - 一条 pid 1,第二条 pid 2,count 应该返回 2。
你可以这样简单地用count替换get:$count = DB::table('tablename')->count(DB::raw('DISTINCT pid'));
也可以这样做:DB::table('tablename')->distinct('pid')->count('pid');
【参考方案1】:
以下应该可以工作
$ad->getcodes()->distinct()->count('pid');
【讨论】:
有一个类似的问题,似乎只是省略了groupBy
就可以了。
Distinct 不接受任何参数。在构建查询时调用 distinct() 只会将受保护的布尔值设置为 true,而忽略该参数。
在 L5.1 上,这仍然无法正常工作。使用count()
似乎会禁用或删除distinct()
。如整个问题所述,使用groupBy()
。编辑:与get()
相比,我发现甚至groupBy()
提供了不同的count()
,然后计算结果数组。
@Jason 我和你做了同样的观察。请参阅我的答案以获得解决方案。
distinct()
函数不接受任何参数。您可以将其更改为$ad->getcodes()->distinct()->count('pid');
,结果相同。【参考方案2】:
这对我有用,所以 尝试这个: $ad->getcodes()->distinct('pid')->count()
【讨论】:
您好,欢迎来到 SO。回答问题时,请提供有关您提供的代码的其他信息。欢迎这样的贡献,但将来其他人可能会从镜头解释中受益【参考方案3】:我遇到了类似的问题,并找到了解决方法。
问题在于 Laravel 的查询构建器处理聚合的方式。它采用返回的第一个结果,然后返回“聚合”值。这通常很好,但是当您将 count 与 groupBy 结合使用时,您将返回每个分组项目的计数。所以第一行的聚合只是第一组的计数(所以可能是 1 或 2 之类的低值)。
所以 Laravel 的计数已经结束,但我将 Laravel 查询构建器与一些原始 SQL 结合起来,以获得我分组结果的准确计数。
对于您的示例,我希望以下内容应该有效(并让您避免获取):
$query = $ad->getcodes()->groupby('pid')->distinct();
$count = count(\DB::select($query->toSql(), $query->getBindings()));
如果您想确保不会浪费时间选择所有列,则可以在构建查询时避免这种情况:
$query = $ad->select(DB::raw(1))->getcodes()->groupby('pid')->distinct();
【讨论】:
【参考方案4】:还有其他人看到这篇文章,但没有找到其他可行的建议吗?
根据具体查询,可能需要不同的方法。就我而言,我需要计算GROUP BY
的结果,例如
SELECT COUNT(*) FROM (SELECT * FROM a GROUP BY b)
或使用COUNT(DISTINCT b)
:
SELECT COUNT(DISTINCT b) FROM a
经过一番摸索,我意识到这两个都没有内置的 Laravel 函数。所以最简单的解决方案是使用 DB::raw
和 count
方法。
$count = $builder->count(DB::raw('DISTINCT b'));
记住,在调用count
之前不要使用groupBy
。如果您需要它来获取行,您可以稍后申请groupBy
。
【讨论】:
$builder 是从哪里来的? @Andrew 您用于查询的 Laravel 查询构建器。例如,一个 Eloquent 对象$books = Book::where(...)->count(...)
->count(DB::raw('DISTINCT b'))
生成与->distinct()->count('b')
相同的SQL查询【参考方案5】:
我遇到了同样的问题。
如果你安装了 laravel 调试栏你可以看到查询并且经常看到问题
$ad->getcodes()->groupby('pid')->distinct()->count()
改成
$ad->getcodes()->distinct()->select('pid')->count()
您需要将值设置为不同的返回值。如果您不设置选择字段,它将返回数据库中的所有列,并且所有列都是唯一的。因此,将查询设置为 distinct 并仅选择构成您可能想要添加的“distinct”值的列。 ->select('pid','date')
获取用户一天内的所有唯一值
【讨论】:
【参考方案6】:这不行吗?
$ad->getcodes()->distinct()->get(['pid'])->count();
请参阅here 进行讨论..
【讨论】:
这不是一个好的解决方案,因为get()
调用会执行查询并从数据库返回结果,然后count()
在Collection上运行。【参考方案7】:
一个更通用的答案可以节省我的时间,希望其他人:
不起作用(返回所有行的计数):
DB::table('users')
->select('first_name')
->distinct()
->count();
修复:
DB::table('users')
->distinct()
->count('first_name');
【讨论】:
【参考方案8】:Distinct 不接受参数,因为它在您的 sql 查询中添加了 DISTINCT,但是,您可能需要定义要选择 distinct 的列名。因此,如果你有
Flight->select('project_id')->distinct()->get()
等同于 SELECT DISTINCT 'project_id' FROM flights
,您现在可以添加其他修饰符,例如 count() 甚至是原始的 eloquent 查询。
【讨论】:
【参考方案9】:$solution = $query->distinct()
->groupBy
(
[
'array',
'of',
'columns',
]
)
->addSelect(
[
'columns',
'from',
'the',
'groupby',
]
)
->get();
记住 group by 是可选的,当您希望计数 group by 排除重复的选择值时,这应该在大多数情况下起作用,addSelect 是一个查询构建器实例方法。
【讨论】:
【参考方案10】:试试这个
$ad->getcodes()->groupby('pid')->distinct()->count('pid')
【讨论】:
【参考方案11】:您可以根据需要使用以下方式获取唯一数据,如下所示,
$data = $ad->getcodes()->get()->unique('email');
$count = $data->count();
希望这会奏效。
【讨论】:
这将从数据库中提取记录,然后执行计数。那是没有效率的。另一方面,$ad->getcodes()->distinct('pid')->count('pid');现在我们不必实际选择记录,而是可以只计算它们,这样更有效【参考方案12】:基于Laravel docs for raw queries,我能够获得一个选择字段的计数,以便在产品模型中使用此代码。
public function scopeShowProductCount($query)
$query->select(DB::raw('DISTINCT pid, COUNT(*) AS count_pid'))
->groupBy('pid')
->orderBy('count_pid', 'desc');
这个外观在控制器中得到了相同的结果:
$products = DB::table('products')->select(DB::raw('DISTINCT pid, COUNT(*) AS count_pid'))->groupBy('pid')->orderBy('count_pid', 'desc')->get();
两个查询的结果转储如下:
#attributes: array:2 [
"pid" => "1271"
"count_pid" => 19
],
#attributes: array:2 [
"pid" => "1273"
"count_pid" => 12
],
#attributes: array:2 [
"pid" => "1275"
"count_pid" => 7
]
【讨论】:
以上是关于Laravel Eloquent - distinct() 和 count() 不能一起正常工作的主要内容,如果未能解决你的问题,请参考以下文章
php Laravel 5 Eloquent CheatSheet #laravel #eloquent
php [Eloquent CheatSheet] Eloquent #laravel #eloquent的常见查询方法