Laravel Eloquent - different () und count () arbeiten nicht richtig zusammen

94

Ich versuche also, die Anzahl der unterschiedlichen Pids für eine Abfrage zu ermitteln, aber der zurückgegebene Wert ist falsch.

Das versuche ich zu tun:

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

Was den Wert "2" zurückgibt, während der Wert, den es zurückgeben soll, "1" sein sollte.

Um dieses Problem zu umgehen, mache ich Folgendes:

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

was gut funktioniert und "1" zurückgibt

Gibt es eine Regel, nach der Anzahl und Unterscheidungskraft nicht in derselben Abfrage enthalten sein können? Ich finde die Problemumgehung "schwer", ich möchte, dass die ursprüngliche Abfrage funktioniert :(

Inigo EC
quelle
Was haben Sie in Ihrer Beispieltabelle in der Datenbank? Und was möchten Sie erreichen? Jetzt sollten Sie wahrscheinlich die Anzahl der unterschiedlichen Werte in der pidSpalte erhalten. Wenn Sie also in Ihrer Tabelle 2 Datensätze haben - einer mit PID 1, der zweite mit PID 2, sollte die Anzahl 2 zurückgeben.
Marcin Nabiałek
Sie können get einfach durch count auf folgende Weise ersetzen: $count = DB::table('tablename')->count(DB::raw('DISTINCT pid')); kann auch tun: DB::table('tablename')->distinct('pid')->count('pid');
bharat

Antworten:

122

Folgendes sollte funktionieren

$ad->getcodes()->distinct('pid')->count('pid');
Suresh Bala
quelle
2
Hatte ein ähnliches Problem und es scheint, als würde man einfach groupByden Trick weglassen.
Jeteon
8
Distinct nimmt keine Argumente an. Wenn Sie beim Erstellen Ihrer Abfrage different () aufrufen, wird der geschützte Boolesche Wert nur auf true gesetzt. Das Argument wird ignoriert.
Matt McDonald
Auf L5.1 und das funktioniert immer noch nicht. Die Verwendung count()scheint das zu deaktivieren oder zu löschen distinct(). Verwenden Sie groupBy()wie in der Frage beschrieben. Bearbeiten: Ich finde sogar, groupBy()dass es ein anderes gibt count()als das get()Zählen des resultierenden Arrays.
Jason
@ Jason Ich habe die gleiche Beobachtung gemacht wie du. Siehe meine Antwort für eine Lösung.
Zoon
21
Die distinct()Funktion akzeptiert keine Argumente. Sie können es $ad->getcodes()->distinct()->count('pid');mit dem gleichen Ergebnis ändern .
Trevor Gehman
26

Eine allgemeinere Antwort, die mir und hoffentlich anderen Zeit gespart hätte:

Funktioniert nicht (gibt die Anzahl aller Zeilen zurück):

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

Die Reparatur:

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

Ist noch jemand auf diesen Beitrag gestoßen und hat keine anderen Vorschläge gefunden, die funktionieren könnten?

Abhängig von der spezifischen Abfrage kann ein anderer Ansatz erforderlich sein. In meinem Fall musste ich entweder die Ergebnisse von a zählen GROUP BY, z

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

oder verwenden COUNT(DISTINCT b):

SELECT COUNT(DISTINCT b) FROM a

Nach einigem Rätsel wurde mir klar, dass es für beide keine eingebaute Laravel-Funktion gab. Die einfachste Lösung war also die Verwendung DB::rawder countMethode.

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

Denken Sie daran, nicht groupByvor dem Anruf zu verwenden count. Sie können sich groupByspäter bewerben , wenn Sie es zum Abrufen von Zeilen benötigen.

Zoon
quelle
Woher kam $ builder?
Andrew
1
@ Andrew Der Laravel-Abfrage-Generator, den Sie für die Abfrage verwenden. Zum Beispiel ein eloquentes Objekt$books = Book::where(...)->count(...)
Zoon
->count(DB::raw('DISTINCT b'))Generieren Sie dieselbe SQL-Abfrage wie->distinct()->count('b')
Trevor Gehman
5

Ich hatte ein ähnliches Problem und fand einen Weg, es zu umgehen.

Das Problem ist die Art und Weise, wie der Abfrage-Generator von Laravel mit Aggregaten umgeht. Es wird das erste zurückgegebene Ergebnis und dann der Gesamtwert zurückgegeben. Dies ist normalerweise in Ordnung, aber wenn Sie count mit groupBy kombinieren, geben Sie eine Anzahl pro gruppiertem Element zurück. Das Aggregat der ersten Zeile ist also nur eine Zählung der ersten Gruppe (also ist etwas Niedriges wie 1 oder 2 wahrscheinlich).

Die Anzahl von Laravel ist also abgelaufen, aber ich habe den Laravel-Abfrage-Generator mit etwas SQL kombiniert, um eine genaue Zählung meiner gruppierten Ergebnisse zu erhalten.

Für Ihr Beispiel erwarte ich, dass Folgendes funktionieren sollte (und Sie das Get vermeiden können):

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

Wenn Sie sicherstellen möchten, dass Sie keine Zeit mit der Auswahl aller Spalten verschwenden, können Sie dies beim Erstellen Ihrer Abfrage vermeiden:

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

Ich bin auf das gleiche Problem gestoßen.

Wenn Sie die Laravel-Debug-Leiste installieren, können Sie die Abfragen und häufig das Problem sehen

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

ändern

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

Sie müssen die Werte so einstellen, dass sie als eindeutig zurückgegeben werden. Wenn Sie die Auswahlfelder nicht festlegen, werden alle Spalten in der Datenbank zurückgegeben und alle sind eindeutig. Setzen Sie die Abfrage daher auf "Unterschiedlich" und wählen Sie nur die Spalten aus, aus denen Ihr "eindeutiger" Wert besteht, für den Sie möglicherweise weitere hinzufügen möchten. ->select('pid','date')um alle eindeutigen Werte für einen Benutzer an einem Tag zu erhalten

Brett
quelle
4

Sie können die folgenden Methoden verwenden, um die eindeutigen Daten gemäß Ihren Anforderungen wie folgt abzurufen:

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

$count = $data->count();

Hoffe das wird funktionieren.

Shahrukh Anwar
quelle
1
Dies funktionierte wie erwartet
Segen Tatenda Kabungaidze
1

Würde das nicht funktionieren?

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

Siehe hier für die Diskussion ..

JonnyFoley
quelle
3
Dies ist keine gute Lösung, da der get()Aufruf die Abfrage ausführt und die Ergebnisse aus der Datenbank zurückgibt und dann count()die Sammlung ausführt .
Trevor Gehman
1
$solution = $query->distinct()
            ->groupBy
            (
                [
                    'array',
                    'of',
                    'columns',
                ]
            )
            ->addSelect(
                [
                    'columns',
                    'from',
                    'the',
                    'groupby',
                ]
            )
            ->get();

Denken Sie daran, dass die Gruppe nach optional ist. Dies sollte in den meisten Fällen funktionieren, wenn eine Zählgruppe nach doppelte Auswahlwerte ausschließen soll. AddSelect ist eine Querybuilder-Instanzmethode.

Daniel Santos
quelle
0

Distinct nimmt keine Argumente an, da DISTINCT in Ihre SQL-Abfrage eingefügt wird. Möglicherweise müssen Sie jedoch den Spaltennamen definieren, mit dem Sie einen bestimmten Namen auswählen möchten. Wenn Sie also Flight->select('project_id')->distinct()->get()gleich sind SELECT DISTINCT 'project_id' FROM flightsund jetzt andere Modifikatoren wie count () oder sogar beredte Abfragen hinzufügen können.

Karl Anthony Baluyot
quelle
0

Basierend auf Laravel-Dokumenten für Rohabfragen konnte ich die Anzahl für ein ausgewähltes Feld ermitteln, um mit diesem Code im Produktmodell zu arbeiten.

public function scopeShowProductCount($query)
{
    $query->select(DB::raw('DISTINCT pid, COUNT(*) AS count_pid'))
          ->groupBy('pid')
          ->orderBy('count_pid', 'desc');
}

Diese Fassade hat dazu beigetragen, das gleiche Ergebnis in der Steuerung zu erzielen:

$products = DB::table('products')->select(DB::raw('DISTINCT pid, COUNT(*) AS count_pid'))->groupBy('pid')->orderBy('count_pid', 'desc')->get();

Der resultierende Speicherauszug für beide Abfragen war wie folgt:

#attributes: array:2 [
  "pid" => "1271"
  "count_pid" => 19
],
#attributes: array:2 [
  "pid" => "1273"
  "count_pid" => 12
],
#attributes: array:2 [
  "pid" => "1275"
  "count_pid" => 7
]
jc_anchor
quelle
-1

Das hat bei mir funktioniert, also versuchen Sie Folgendes: $ ad-> getcodes () -> unique ('pid') -> count ()

Sushant Yadav
quelle
Hallo willkommen bei SO. Bei der Beantwortung einer Frage geben Sie bitte zusätzliche Informationen zu dem von Ihnen angegebenen Code an. Beiträge wie dieser sind willkommen, aber andere können in Zukunft von einer
Schusserklärung
-3

Versuche dies

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