Wenn ich array_agg
Namen sammle, werden meine Namen durch Kommas getrennt. Wenn jedoch ein null
Wert vorhanden ist , wird diese Null auch als Name im Aggregat verwendet. Zum Beispiel :
SELECT g.id,
array_agg(CASE WHEN g.canonical = 'Y' THEN g.users ELSE NULL END) canonical_users,
array_agg(CASE WHEN g.canonical = 'N' THEN g.users ELSE NULL END) non_canonical_users
FROM groups g
GROUP BY g.id;
es kehrt ,Larry,Phil
statt nur zurück Larry,Phil
(in meinem 9.1.2 zeigt es NULL,Larry,Phil
). wie in dieser Geige
Wenn ich stattdessen verwende string_agg()
, werden mir nur die Namen (ohne leere Kommas oder Nullen) wie hier angezeigt
Das Problem ist, dass ich Postgres 8.4
auf dem Server installiert habe und string_agg()
dort nicht funktioniert. Gibt es eine Möglichkeit, array_agg ähnlich wie string_agg () arbeiten zu lassen?
Antworten:
SQL Fiddle
Oder einfacher und möglicherweise billiger,
array_to_string
wodurch Nullen beseitigt werden:SQL Fiddle
quelle
array_to_string(array_agg(...))
Sie auch verwendenstring_agg
.Mit postgresql-9.3 kann man das machen;
Update : mit postgresql-9.4;
quelle
Bei der Lösung der allgemeinen Frage des Entfernens von Nullen aus Array-Aggregaten gibt es zwei Hauptmethoden, um das Problem anzugreifen: entweder array_agg (unnest (array_agg (x)) oder das Erstellen eines benutzerdefinierten Aggregats.
Die erste hat die oben gezeigte Form :
Der Zweite:
Das zweite anzurufen ist (natürlich) etwas schöner als das erste:
quelle
Ich füge dies hinzu, obwohl dieser Thread ziemlich alt ist, aber ich bin auf diesen netten Trick gestoßen, der auf kleinen Arrays ziemlich gut funktioniert. Es läuft auf Postgres 8.4+ ohne zusätzliche Bibliotheken oder Funktionen.
Die
array_to_string()
Methode entfernt tatsächlich die Nullen.quelle
Wenn Sie nach einer modernen Antwort auf die allgemeine Frage suchen, wie ein NULL aus einem Array entfernt werden kann , lautet dies:
Ich war besonders neugierig auf Leistung und wollte dies mit der bestmöglichen Alternative vergleichen:
Ein pgbench-Test hat (mit hoher Sicherheit) bewiesen, dass array_remove () etwas mehr als doppelt so schnell ist . Ich habe meinen Test mit Zahlen mit doppelter Genauigkeit mit einer Vielzahl von Arraygrößen (10, 100 und 1000 Elemente) und zufälligen NULL-Werten dazwischen durchgeführt.
quelle
Wie in den Kommentaren vorgeschlagen, können Sie eine Funktion schreiben, um Nullen in einem Array zu ersetzen. Wie jedoch auch in dem in den Kommentaren verknüpften Thread ausgeführt, beeinträchtigt diese Art die Effizienz der Aggregatfunktion, wenn Sie ein Aggregat erstellen müssen , teilen Sie es und aggregieren Sie es erneut.
Ich denke, Nullen im Array zu behalten ist nur eine (möglicherweise unerwünschte) Funktion von Array_Agg. Sie können Unterabfragen verwenden, um dies zu vermeiden:
SQL FIDDLE
quelle
Es ist sehr einfach, erstellen Sie zunächst einen neuen - (Minus-) Operator für Text [] :
Und subtrahieren Sie einfach das Array [null]:
Das ist alles:
{J, N}
quelle
array_agg(x) FILTER (WHERE x is not null)
scheint viel einfacher zu sein: dbfiddle.uk/… und Sie brauchen nicht wirklich Ihre eigene Funktion, Sie können einfacharray_remove()
dbfiddle.uk/… verwendenEine größere Frage ist, warum alle Benutzer- / Gruppenkombinationen gleichzeitig gezogen werden. Garantiert kann Ihre Benutzeroberfläche nicht alle diese Daten verarbeiten. Das Hinzufügen von Paging zu übergroßen Daten ist ebenfalls eine schlechte Idee. Lassen Sie Ihre Benutzer den Satz filtern, bevor sie Daten sehen. Stellen Sie sicher, dass Ihr JOIN-Optionssatz in der Liste enthalten ist, damit sie nach Leistung filtern können, wenn sie möchten. Manchmal machen 2 Abfragen Benutzer glücklicher, wenn beide schnell sind.
quelle