PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Comment utiliser array_agg() pour varchar[]

La fonction d'agrégation standard array_agg() ne fonctionne que pour les types de base, pas les types de tableau en entrée. (Mais Postgres 9.5+ a une nouvelle variante de array_agg() ça peut !)

Vous pouvez utiliser la fonction d'agrégation personnalisée array_agg_mult() comme défini dans cette réponse connexe :
Sélection de données dans un tableau Postgres

Créez-le une fois par base de données. Votre requête pourrait alors fonctionner comme ceci :

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;

Il y a une justification détaillée dans la réponse liée.

Les étendues doivent correspondre

En réponse à votre commentaire, considérez cette citation du manuel sur les types de tableaux :

Les tableaux multidimensionnels doivent avoir des étendues correspondantes pour chaque dimension. Une non-concordance provoque une erreur.

Il n'y a aucun moyen de contourner cela, le type de tableau ne permet pas une telle incompatibilité dans Postgres. Vous pourriez remplissez vos tableaux avec des valeurs NULL afin que toutes les dimensions aient des étendues correspondantes.

Mais je préférerais traduire les tableaux en listes séparées par des virgules avec array_to_string() dans le cadre de cette requête et utilisez string_agg() pour agréger le text - de préférence avec un séparateur différent. En utilisant une nouvelle ligne dans mon exemple :

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

Normaliser

Vous voudrez peut-être envisager de normaliser votre schéma pour commencer. En règle générale, vous implémenteriez une telle relation n:m avec une table séparée, comme indiqué dans cet exemple :
Comment implémenter une relation plusieurs-à-plusieurs dans PostgreSQL ?