Dies mag recht einfach sein, hat aber keine Ahnung, wie.
Ich habe eine Tabelle, die wiederholte Werte für ein bestimmtes Nicht-Schlüsselspaltenfeld haben kann. Wie schreibe ich eine SQL-Abfrage mit Query Builder oder Eloquent, die Zeilen mit unterschiedlichen Werten für diese Spalte abruft?
Beachten Sie, dass ich diese Spalte nicht nur abrufe, sondern in Verbindung mit anderen Spaltenwerten, sodass sie distinct()
möglicherweise nicht wirklich funktioniert. Diese Frage kann also im Grunde sein, wie die Spalte angegeben werden soll, die in einer Abfrage, distinct()
die keine Parameter akzeptiert, unterschieden werden soll.
where()
Wie kann ich das beheben, wenn ich ein Problem hinzufüge ?group by
ist nicht dasselbe wiedistinct
.group by
ändert das Verhalten von Aggregatfunktionen wiecount()
in der SQL-Abfrage.distinct
Das Verhalten solcher Funktionen wird nicht geändert, sodass Sie je nach verwendeter Funktion unterschiedliche Ergebnisse erhalten.In Eloquent können Sie auch Folgendes abfragen:
$users = User::select('name')->distinct()->get();
quelle
Note that I am not fetching that column only, it is in conjunction with other column values
$users = User::select('column1', 'column2', 'column3')->distinct()->get();
->orderBy('name')
wenn Sie dies mit verwenden möchtenchunk
.in eloquent können Sie dies verwenden
groupBy ruft tatsächlich die unterschiedlichen Werte ab. Tatsächlich kategorisiert groupBy dieselben Werte, sodass wir Aggregatfunktionen für sie verwenden können. In diesem Szenario haben wir jedoch keine Aggregatfunktionen. Wir wählen nur den Wert aus, der dazu führt, dass das Ergebnis unterschiedliche Werte aufweist
quelle
in_array()
Funktion überprüfen möchten, ob ein Element vorhanden ist , es nie funktioniert. Um das Problem zu beheben, habe ich->lists()
stattdessen versucht (Version 5.2). Also,$users = User::select('name')->groupBy('name')->lists('name');
funktionierte gut für PHPsin_array()
;Obwohl ich zu spät komme, um darauf zu antworten, wäre es besser, mit Eloquent eindeutige Aufzeichnungen zu erhalten
quelle
get()
Methode übergeben kann (und ich habe auch diefirst()
Methode getestet ), was der Verwendung derselect()
Methode entspricht, wie in einigen Antworten hier gezeigt. Obwohl irgendwiegroupBy
immer noch die höchste Punktzahl zu erzielen scheint. Dies wäre jedoch wirklich eindeutig, wenn dies die einzige Spalte ist, die ich auswähle.$user_names = User::distinct()->count(['name']);
funktioniert auchDas Gruppieren nach funktioniert nicht, wenn die Datenbankregeln nicht zulassen, dass sich eines der Auswahlfelder außerhalb einer Aggregatfunktion befindet. Verwenden Sie stattdessen die Laravel-Sammlungen .
Jemand wies darauf hin, dass dies für große Sammlungen möglicherweise nicht besonders leistungsfähig ist. Ich würde empfehlen, der Sammlung einen Schlüssel hinzuzufügen. Die zu verwendende Methode heißt keyBy . Dies ist die einfache Methode.
Mit dem keyBy können Sie auch eine Rückruffunktion für komplexere Dinge hinzufügen ...
Wenn Sie große Sammlungen durchlaufen müssen, können Sie das Leistungsproblem beheben, indem Sie einen Schlüssel hinzufügen.
quelle
Beachten Sie, dass
groupBy
die oben verwendete Funktion für Postgres nicht funktioniert.Die Verwendung
distinct
ist wahrscheinlich eine bessere Option - z$users = User::query()->distinct()->get();
Wenn Sie verwenden
query
, können Sie alle Spalten wie gewünscht auswählen.quelle
$users = User::select('column1', 'column2', 'column3')->distinct()->get();
Ruft alle drei Coulmns für unterschiedliche Zeilen in der Tabelle ab. Sie können beliebig viele Spalten hinzufügen.quelle
** **.
Getestet für Laravel 5.8
** **.
Da Sie alle Spalten aus der Tabelle abrufen möchten, können Sie alle Daten erfassen und anschließend mithilfe der Funktion "Sammlungen" mit dem Namen " Einzigartig" filtern
oder
Weitere Informationen finden Sie in den Laravel Collection-Dokumentationen
BEARBEITEN: Möglicherweise haben Sie Probleme mit der Leistung. Wenn Sie Unique () verwenden, werden alle Daten zuerst aus der Benutzertabelle abgerufen und dann von Laravel gefiltert. Dieser Weg ist nicht gut, wenn Sie viele Benutzerdaten haben. Sie können den Abfrage-Generator verwenden und jedes Feld aufrufen, das Sie verwenden möchten. Beispiel:
quelle
Ich fand, dass diese Methode (für mich) ziemlich gut funktioniert, um eine flache Reihe eindeutiger Werte zu erzeugen:
Wenn Sie
->toSql()
diesen Abfrage-Generator ausgeführt haben, wird eine Abfrage wie die folgende generiert:Das
->pluck()
wird von illuminate \ collection lib behandelt (nicht über eine SQL-Abfrage).quelle
Ich hatte die gleichen Probleme beim Versuch, eine Liste aller eindeutigen Threads zu füllen, die ein Benutzer mit anderen Benutzern hatte. Das hat den Trick für mich getan
quelle
quelle
Für diejenigen, die mögen, dass ich den gleichen Fehler mache. Hier ist die ausgearbeitete Antwort, die in Laravel 5.7 getestet wurde
A. Datensätze in der DB
B. Gewünschtes gruppiertes Ergebnis
Übergeben Sie also nur die Spalten
"select()"
, deren Werte gleich sind. Zum Beispiel :'type','url'
. Sie können weitere Spalten hinzufügen, sofern diese denselben Wert haben wie'updated_at'
.Wenn Sie versuchen, zu übergeben
"created_at"
oder"id"
zu übergeben"select()"
, erhalten Sie dieselben Datensätze wie A. Da sie für jede Zeile in der Datenbank unterschiedlich sind.quelle