2009-02-10 6 views
29

Ich habe eine Tabelle wie folgt aufgebaut:Concatenate mehr Zeilen in einem Array mit SQL auf PostgreSQL

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

Ich mag diese Tabelle abzufragen ein Ergebnis wie diese zu erhalten:

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

Ich kann keinen Weg finden, das zu tun. Ist das möglich ? Wie ?

Vielen Dank.

+0

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

Antwort

52

Dieses ein Postgres ist seit einigen Versionen integriert, sodass Sie nicht mehr Ihre eigenen definieren müssen, der Name ist 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} 

(dies ist postgres 8.4.8).

Beachten Sie, dass ORDER BY nicht angegeben ist, daher hängt die Reihenfolge der Ergebniszeilen von der verwendeten Gruppierungsmethode (hier Hash) ab, dh sie ist nicht definiert. Beispiel:

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} 

Nun, ich weiß nicht, warum Sie {10,2,4,6,8} erhalten und {9,7,3,1,5}, da generate_series() sollte die schicken Reihen in der Reihenfolge.

+0

In PostgreSQL 8.4.8 gibt das zurück: {10,2,4,6,8} und { 9,7,3,1,5} Ich denke, die obige Ausgabe ist von Version 9. – SabreWolfy

+0

Antwort bearbeitet ... – peufeu

+0

Ich weiß auch nicht, warum die Zeilen/Elemente in der Reihenfolge zurückgegeben werden, die ich sie sehe Ich habe den Code einfach kopiert und eingefügt, um zu sehen, was er getan hat. – SabreWolfy

16

Sie müssen eine Aggregatfunktion erstellen, z.

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

dann

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

HTH

+0

I Erhalte den folgenden Fehler beim Versuch, diese Aggregatfunktion zu erstellen: FEHLER: Syntaxfehler bei oder nahe "(" – SomethingOn

+0

Verwenden Sie PostgreSQL? – SuN

1

Hier ist der Code für die angeforderte Ausgabe.

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;