web-dev-qa-db-ja.com

Laravel Eloquent - distinct()とcount()が正しく連携していない

だから私はクエリ上の異なるpidの数を取得しようとしていますが、戻り値は間違っています。

これは私がやろうとしていることです:

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

whatは値 "2"を返しますが、返すべき値は "1"でなければなりません。

回避策として、これをやっています:

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

正常に動作し、「1」を返すもの

Countとdistinctを同じクエリに指定できないという規則はありますか?私は回避策の種類が "重い"であることに気付いた、私は元のクエリを動作させたいのですが

68
Inigo EC

以下はうまくいくはずです

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

もっと一般的な答えで、私の時間を節約できたでしょう。

動作しません(全行数を返します):

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

修正:

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

他に誰かがこの記事に出くわし、そして他の提案を見つけられないのですか?

特定の照会に応じて、異なる方法が必要になる場合があります。私の場合、私はGROUP BYの結果を数える必要があります。

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

またはCOUNT(DISTINCT b)を使用してください。

SELECT COUNT(DISTINCT b) FROM a

少し戸惑った後、私はこれらのどちらにも組み込みのLaravel関数がないことに気づきました。そのため、最も簡単な解決策は、countメソッドでDB::rawを使用することでした。

$count = $builder->count(DB::raw('DISTINCT b'));

groupByを呼び出す前にcountを使用しないでください。行を取得するために必要に応じて、後でgroupByを適用できます。

11
Zoon

私は同様の問題を抱えていて、それを回避する方法を見つけました。

問題は、Laravelのクエリービルダーが集計を処理する方法です。最初に返された結果を受け取り、それから 'aggregate'値を返します。これは通常は問題ありませんが、countとgroupByを組み合わせると、グループ化された項目ごとにカウントが返されます。したがって、最初の行の集計は最初のグループの数にすぎません(したがって、1または2のような低い値になる可能性があります)。

そのため、Laravelのカウントは外れましたが、Laravelクエリビルダーと生のSQLを組み合わせて、グループ化された結果の正確なカウントを取得しました。

あなたの例では、私は以下がうまくいくはずです(そしてgetを避けるようにしましょう)。

$query = $ad->getcodes()->groupby('pid')->distinct();
$count = count(\DB::select($query->toSql(), $query->getBindings()));

すべての列を選択する時間を無駄にしないようにするには、クエリを作成するときにこれを回避できます。

 $query = $ad->select(DB::raw(1))->getcodes()->groupby('pid')->distinct();
3
Matt McDonald

これでうまくいきませんか。

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

議論のために ここ を見てください..

1
JonnyFoley

SqlクエリにDISTINCTが追加されているため、個別に引数を取ることはありませんが、区別して選択したい列名を定義する必要があるかもしれません。したがって、もしFlight->select('project_id')->distinct()->get()SELECT DISTINCT 'project_id' FROM flightsと同等であれば、count()や生の好奇心旺盛なクエリのような他の修飾子を追加することができます。

私は同じ問題に出くわした。

あなたがlaravelデバッグバーをインストールするならば、あなたは質問を見ることができて、しばしば問題を見ることができます

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

への変更

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

異なる値を返すように値を設定する必要があります。選択フィールドを設定しないと、データベース内のすべての列が返され、すべて一意になります。そのため、クエリをdistinctに設定し、さらに追加する必要がある可能性がある 'distinct'値を構成する列のみを選択します。 ->select('pid','date')は、一日に一人のユーザーに固有の値をすべて取得するためのものです。

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

Group byはオプションであることを忘れないでください。これは、count group byで重複したselect値を除外したい場合、ほとんどの場合に機能するはずです。addSelectはquerybuilderインスタンスメソッドです。

0
Daniel Santos
DB::table('adverts')->distinct()->select('ad_advertiser')->get()
0
Gurpreet Singh