PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Come usare array_agg() per varchar[]

La funzione aggregata standard array_agg() funziona solo per i tipi di base, non per i tipi di array come input.(Ma Postgres 9.5+ ha una nuova variante di array_agg() che può!)

Puoi utilizzare la funzione di aggregazione personalizzata array_agg_mult() come definito in questa risposta correlata:
Selezione dei dati in un array Postgres

Crealo una volta per database. Quindi la tua query potrebbe funzionare in questo modo:

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;

C'è una motivazione dettagliata nella risposta collegata.

Le estensioni devono corrispondere

In risposta al tuo commento, considera questa citazione dal manuale sui tipi di array:

Gli array multidimensionali devono avere estensioni corrispondenti per ciascuna dimensione. Una mancata corrispondenza causa un errore.

Non c'è modo di aggirarlo, il tipo di array non consente una tale discrepanza in Postgres. Potresti riempi gli array con valori NULL in modo che tutte le dimensioni abbiano estensioni corrispondenti.

Ma preferirei tradurre gli array in elenchi separati da virgole con array_to_string() ai fini di questa query e utilizzare string_agg() per aggregare il text - preferibilmente con un separatore diverso. Usando una nuova riga nel mio esempio:

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   ...

Normalizza

Potresti prendere in considerazione la normalizzazione del tuo schema per cominciare. In genere, implementeresti una tale relazione n:m con una tabella separata come descritto in questo esempio:
Come implementare una relazione molti-a-molti in PostgreSQL?