ChatGPT解决这个技术问题 Extra ChatGPT

Laravel Eloquent - distinct() 和 count() 不能一起正常工作

所以我试图在查询中获取不同 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。
您可以通过这种方式简单地将 get 替换为 count:$count = DB::table('tablename')->count(DB::raw('DISTINCT pid')); 也可以:DB::table('tablename')->distinct('pid')->count('pid');

M
Mike Ross

以下应该工作

$ad->getcodes()->distinct()->count('pid');

有一个类似的问题,似乎只是省略了 groupBy 就可以了。
Distinct 不接受任何参数。在构建查询时调用 distinct() 只会将受保护的布尔值设置为 true,而忽略该参数。
在 L5.1 上,这仍然无法正常工作。使用 count() 似乎禁用或删除了 distinct()。按照整个问题的说明使用 groupBy()。编辑:我发现甚至 groupBy()get() 相比提供了不同的 count(),然后计算结果数组。
@Jason 我和你做了同样的观察。请参阅我的答案以获取解决方案。
distinct() 函数不接受任何参数。您可以将其更改为 $ad->getcodes()->distinct()->count('pid');,结果相同。
A
Andrew

一个更通用的答案可以节省我的时间,希望其他人:

不起作用(返回所有行的计数):

DB::table('users')
            ->select('first_name')
            ->distinct()
            ->count();

修复:

DB::table('users')
            ->distinct()
            ->count('first_name');

A
Alexis Wilke

还有其他人看到这篇文章,但没有找到其他可行的建议吗?

根据具体查询,可能需要不同的方法。就我而言,我需要计算 GROUP BY 的结果,例如

SELECT COUNT(*) FROM (SELECT * FROM a GROUP BY b)

或使用 COUNT(DISTINCT b)

SELECT COUNT(DISTINCT b) FROM a

经过一番困惑,我意识到这两个都没有内置的 Laravel 函数。因此,最简单的解决方案是将 DB::rawcount 方法一起使用。

$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 查询
S
Shahrukh Anwar

您可以根据需要使用以下方式获取唯一数据,如下所示,

$data = $ad->getcodes()->get()->unique('email');

$count = $data->count();

希望这会奏效。


这将从数据库中提取记录,然后执行计数。那是没有效率的。另一方面,$ad->getcodes()->distinct('pid')->count('pid');现在我们不必实际选择记录,而是可以只计算它们,这样更有效
M
Matt McDonald

我遇到了类似的问题,并找到了解决它的方法。

问题在于 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();

B
Brett

我遇到了同样的问题。

如果您安装 laravel 调试栏,您可以看到查询并经常看到问题

$ad->getcodes()->groupby('pid')->distinct()->count()

改成

$ad->getcodes()->distinct()->select('pid')->count()

您需要将值设置为不同的返回。如果您不设置选择字段,它将返回数据库中的所有列,并且所有列都是唯一的。因此,将查询设置为 distinct 并仅选择构成您可能想要添加的“distinct”值的列。 ->select('pid','date') 获取用户一天内的所有唯一值


D
Daniel Santos
$solution = $query->distinct()
            ->groupBy
            (
                [
                    'array',
                    'of',
                    'columns',
                ]
            )
            ->addSelect(
                [
                    'columns',
                    'from',
                    'the',
                    'groupby',
                ]
            )
            ->get();

请记住 group by 是可选的,当您希望 count group by 排除重复的选择值时,这应该在大多数情况下工作,addSelect 是一个查询构建器实例方法。


J
J Foley

这不行吗?

$ad->getcodes()->distinct()->get(['pid'])->count();

有关讨论,请参见 here


这不是一个好的解决方案,因为 get() 调用将执行查询并从数据库返回结果,然后 count() 在 Collection 上运行。
j
jc_anchor

根据 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
]

K
Karl Anthony Baluyot

Distinct 不接受参数,因为它在您的 sql 查询中添加了 DISTINCT,但是,您可能需要定义要选择 distinct 的列名。因此,如果您有 Flight->select('project_id')->distinct()->get()SELECT DISTINCT 'project_id' FROM flights 等效,您现在可以添加其他修饰符,例如 count() 甚至是原始的 eloquent 查询。


S
Sushant Yadav

这对我有用,所以试试这个:$ad->getcodes()->distinct('pid')->count()


嗨,欢迎来到 SO。回答问题时,请提供有关您提供的代码的其他信息。欢迎这样的贡献,但将来其他人可能会从镜头解释中受益
x
xiaoxiao

尝试这个

$ad->getcodes()->groupby('pid')->distinct()->count('pid')