web-dev-qa-db-fra.com

Combiner array_agg et unnest

Étant donné un ensemble de données (avec un index GIN sur values):

key | values
-------------
 1  | {4,2,1}
 1  | {2,5}
 2  | {4,1,3}

Je veux agréger les tableaux:

key | values
-------------
 1  | {4,2,1,5}
 2  | {4,1,3}

Ma première pensée n'a pas fonctionné:

SELECT key, array_agg(DISTINCT unnest(values)) AS values FROM data GROUP BY key

[0A000] ERREUR: les appels de fonction d'agrégation ne peuvent pas contenir d'appels de fonction renvoyant un ensemble
Astuce: Vous pourriez être en mesure de déplacer la fonction de retour d'ensemble dans un élément LATERAL FROM.

Ne pas connaître LATERAL FROM, il n'est pas évident pour moi comment obtenir la sortie souhaitée.

3
OrangeDog

Vous devez faire le plus simple dans une sous-requête:

select d."key", array_agg(distinct x.v) 
from data d
  cross join lateral unnest(d."values") as x(v)
group by d."key";

Les fonctions renvoyant un ensemble (comme unnest()) doivent en général être utilisées dans la partie from d'une requête. Mais pour pouvoir référencer une colonne du tableau, vous avez besoin d'un jointure latérale .

from data cross join lateral unnest(...) est une manière explicite d'écrire from data, unnest(...) qui génère également une jointure croisée. Mais je préfère l'opérateur explicite cross join Pour documenter que j'avais effectivement l'intention d'écrire une jointure croisée, plutôt qu'accidentellement.

Cela ne préservera cependant pas l'ordre des éléments.

Exemple en ligne: https://rextester.com/TVIDB57711

6