2009-02-10 7 views
29

J'ai une table construite comme ceci:lignes multiples Concaténer dans un tableau avec SQL sur PostgreSQL

oid | identifier | value 
1 | 10   | 101 
2 | 10   | 102 
3 | 20   | 201 
4 | 20   | 202 
5 | 20   | 203 

Je voudrais interroger ce tableau pour obtenir un résultat comme celui-ci:

identifier | values[] 
10   | {101, 102} 
20   | {201, 202, 203} 

Je n'arrive pas à trouver un moyen de le faire. Est-ce possible ? Comment ?

Merci beaucoup.

+0

Voir ici: http://stackoverflow.com/questions/43870/how-to-concatenate-strings-of-a-string-field-in-a-postgresql-group-by-query – Quassnoi

Répondre

52

C'est un postgres construit en quelques versions depuis un si vous ne avez plus besoin de définir vos propres, le nom est array_agg().

test=> select array_agg(n) from generate_series(1,10) n group by n%2; 
    array_agg 
-------------- 
{1,3,5,7,9} 
{2,4,6,8,10} 

(c'est postgres 8.4.8).

Notez qu'aucun ORDER BY n'est spécifié, donc l'ordre des lignes de résultats dépend de la méthode de regroupement utilisée (ici, hash), c'est-à-dire qu'elle n'est pas définie. Exemple:

test=> select n%2, array_agg(n) from generate_series(1,10) n group by (n%2); 
?column? | array_agg 
----------+-------------- 
     1 | {1,3,5,7,9} 
     0 | {2,4,6,8,10} 

test=> select (n%2)::TEXT, array_agg(n) from generate_series(1,10) n group by (n%2)::TEXT; 
text | array_agg 
------+-------------- 
0 | {2,4,6,8,10} 
1 | {1,3,5,7,9} 

Maintenant, je ne sais pas pourquoi vous obtenez {10,2,4,6,8} et {9,7,3,1,5}, depuis generate_series() doit envoyer le rangées dans l'ordre.

+0

Dans PostgreSQL 8.4.8 cela retourne: {10,2,4,6,8} et { 9,7,3,1,5} Je pense que la sortie ci-dessus est de la version 9. – SabreWolfy

+0

réponse éditée ... – peufeu

+0

Je ne sais pas non plus pourquoi les lignes/éléments sont retournés dans l'ordre où je les vois. juste copié le code et l'a collé pour voir ce qu'il a fait. – SabreWolfy

16

Vous devez créer une fonction d'agrégation, par ex.

CREATE AGGREGATE array_accum (anyelement) 
(
sfunc = array_append, 
stype = anyarray, 
initcond = '{}' 
); 

puis

SELECT identifier, array_accum(value) AS values FROM table GROUP BY identifier; 

HTH

+0

I obtenez l'erreur suivante lorsque vous essayez de créer cette fonction d'agrégation: ERREUR: erreur de syntaxe à ou près de "(" – SomethingOn

+0

Utilisez-vous PostgreSQL? – SuN

1

Voici le code de la sortie demandée.

select identifier, array_agg(value) 
from (
    values 
    (1 , 10   , 101), 
    (2 , 10   , 102), 
    (3 , 20   , 201), 
    (4 , 20   , 202), 
    (5 , 20   , 203) 
) as tab (oid, identifier, value) 
group by identifier 
order by identifier; 
Questions connexes