PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Verwendung von array_agg() für varchar[]

Die Standardaggregatfunktion array_agg() funktioniert nur für Basistypen, nicht für Array-Typen als Eingabe. (Aber Postgres 9.5+ hat eine neue Variante von array_agg() das kann!)

Sie könnten die benutzerdefinierte Aggregatfunktion array_agg_mult() verwenden wie in dieser verwandten Antwort definiert:
Daten in einem Postgres-Array auswählen

Erstellen Sie es einmal pro Datenbank. Dann könnte Ihre Abfrage so aussehen:

SELECT use.user_sched_id, array_agg(se.sched_entry_id) AS seids
      ,array_agg_mult(ARRAY[se.min_crew]) AS min_crew_arr
FROM   base.sched_entry se
LEFT   JOIN base.user_sched_entry use USING (sched_entry_id)
WHERE  se.sched_entry_id = ANY(ARRAY[623, 625])
GROUP  BY user_sched_id;

Eine ausführliche Begründung finden Sie in der verlinkten Antwort.

Extents müssen übereinstimmen

Betrachten Sie als Antwort auf Ihren Kommentar dieses Zitat aus dem Handbuch zu Array-Typen:

Mehrdimensionale Arrays müssen übereinstimmende Extents für jede Dimension haben. Eine Nichtübereinstimmung führt zu einem Fehler.

Daran führt kein Weg vorbei, der Array-Typ lässt eine solche Diskrepanz in Postgres nicht zu. Sie könnten Füllen Sie Ihre Arrays mit NULL-Werten auf, sodass alle Dimensionen übereinstimmende Extents haben.

Aber ich würde die Arrays lieber mit array_to_string() in eine kommaseparierte Liste übersetzen für diese Abfrage und verwenden Sie string_agg() um den text zu aggregieren - vorzugsweise mit einem anderen Trennzeichen. Verwenden eines Zeilenumbruchs in meinem Beispiel:

SELECT use.user_sched_id, array_agg(se.sched_entry_id) AS seids
      ,string_agg(array_to_string(se.min_crew, ','), E'\n') AS min_crews
FROM   ...

Normalisieren

Vielleicht möchten Sie zunächst Ihr Schema normalisieren. Typischerweise würden Sie eine solche n:m-Beziehung mit einer separaten Tabelle implementieren, wie in diesem Beispiel skizziert:
Wie implementiert man eine Viele-zu-Viele-Beziehung in PostgreSQL?