Laravel Eloquent -distinct()とcount()が一緒に正しく機能しない


95

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

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

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

値「2」を返すものは、「1」でなければなりません。

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

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

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

カウントとディスティンクトを同じクエリに含めることができないルールはありますか?私は回避策が「重い」と感じているので、元のクエリを機能させたい:(


データベースのサンプルテーブルには何がありますか?そして、何を達成したいですか?今、あなたはおそらくにおける個別値の数を取得する必要がありpid、列なので、あなたがテーブルに持っている場合は2つのレコード- pidを1と1は、第二のPID 2と、カウントは2。返す必要があります
マルチンNabiałek

あなたは、単にこのように、カウントを取得置き換えることができます $count = DB::table('tablename')->count(DB::raw('DISTINCT pid')); も行うことができます DB::table('tablename')->distinct('pid')->count('pid');
バーラト

回答:


123

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

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

2
同様の問題があり、取り除いただけで問題が解決したようgroupByです。
jeteon

8
Distinctは引数を取りません。クエリを構築するときにdistinct()を呼び出すと、保護されたブール値がtrueに設定されるだけで、引数は無視されます。
Matt McDonald、

L5.1では、これはまだ機能しません。を使用するcount()と、が無効になるか削除されdistinct()ます。groupBy()質問全体を通して説明されているように使用します。編集:結果の配列を数えることと比較しgroupBy()て異なるcount()ものを提供していることさえわかっていget()ます。
Jason

@ジェイソン私はあなたと同じ観察をしました。解決策については私の答えを参照してください。
Zoon

21
このdistinct()関数は引数を取りません。に変更し$ad->getcodes()->distinct()->count('pid');ても同じ結果になります。
Trevor Gehman 2017

26

時間を節約できるより一般的な答え、そしてうまくいけば他の人も:

機能しません(すべての行の数を返します):

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

修正:

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

17

他の誰かがこの投稿に出くわし、他に機能する提案を見つけていませんか?

特定のクエリによっては、別のアプローチが必要になる場合があります。私の場合、の結果を数える必要がありました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'));

groupBy呼び出す前に使用しないでくださいcountgroupBy行を取得するために必要な場合は、後で適用できます。


$ builderはどこから来たのですか?
Andrew

1
@Andrewクエリに使用しているLaravelクエリビルダー。たとえば、雄弁なオブジェクト$books = Book::where(...)->count(...)
Zoon

->count(DB::raw('DISTINCT b'))同じSQLクエリを生成する->distinct()->count('b')
Trevor Gehman

5

私にも同様の問題があり、それを回避する方法を見つけました。

問題は、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

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

laravelデバッグバーをインストールすると、クエリを確認でき、問題を頻繁に確認できます

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

への変更

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

異なる値として返すには、値を設定する必要があります。選択フィールドを設定しない場合、データベース内のすべての列が返され、すべてが一意になります。したがって、クエリを個別に設定し、追加したい「個別の」値を構成する列のみを選択します。->select('pid','date')1日のユーザーのすべての一意の値を取得する


4

次の方法を使用して、必要に応じて一意のデータを取得できます。

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

$count = $data->count();

これがうまくいくことを願っています。


1

これはうまくいきませんか?

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

議論についてはここを参照してください。


3
get()呼び出しはクエリを実行してデータベースから結果を返しcount()、コレクションで実行されるため、これは適切なソリューションではありません。
Trevor Gehman 2017

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

group byはオプションであることを覚えておいてください。これは、重複した選択値を除外するためにcount group byが必要な場合にほとんど機能します。addSelectはquerybuilderインスタンスメソッドです。


0

DistinctはSQLクエリにDISTINCTを追加するため、引数を取りません。ただし、個別に選択する列名を定義する必要があります。したがって、あなた Flight->select('project_id')->distinct()->get()が同等でSELECT DISTINCT 'project_id' FROM flightsあり、count()や生の雄弁なクエリのような他の修飾子を追加する場合があります。


0

未加工クエリのLaravelドキュメントに基づいて、製品モデルでこのコードを使用する選択フィールドの数を取得できました。

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
]

-1

これは私のために働いていたので、これを試してください:$ ad-> getcodes()-> distinct( 'pid')-> count()


SOへようこそ。質問に答えるときは、提供するコードに関する追加情報を提供してください。このような貢献は歓迎されますが、将来的には他の人もショットの説明から恩恵を受ける可能性があります
Deepend

-3

これを試して

$ad->getcodes()->groupby('pid')->distinct()->count('pid')
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.