2012-08-01 20 views
9

Ich habe folgende Daten:Auswählen von Daten in eine Postgres Array

name   id    url 

John   1    someurl.com 
Matt   2    cool.com 
Sam   3    stackoverflow.com 

Wie kann ich eine SQL-Anweisung in Postgres schreiben, um diese Daten in ein mehrdimensionales Array zu wählen, das heißt:

{{John, 1, someurl.com}, {Matt, 2, cool.com}, {Sam, 3, stackoverflow.com}} 

Ich habe diese Art der Array-Nutzung schon einmal in Postgres gesehen, aber ich habe keine Ahnung, wie man Daten aus einer Tabelle in dieses Array-Format auswählt.

Angenommen, dass alle Spalten vom Typ text sind.

Antwort

21

Sie können nicht array_agg() verwenden multidimensionalen Arrays zu erzeugen, zumindest nicht bis zu PostgreSQL 9.4.
(Aber die kommenden Postgres 9.5 Schiffe ein new variant of array_agg(), die können!)

Was Sie aus @Matt Ball's query erhalten eine Reihe von Datensätzen ist (the_table[]).

Ein Array kann nur Elemente desselben Basistyps enthalten. Sie haben offensichtlich Nummern- und String-Typen. Konvertiere alle Spalten (die nicht schon sind) in text, damit es funktioniert.

Sie können eine Aggregatfunktion dafür erstellen, wie ich Ihnen zuvor here gezeigt habe.

CREATE AGGREGATE array_agg_mult (anyarray) (
    SFUNC  = array_cat 
    ,STYPE  = anyarray 
    ,INITCOND = '{}' 
); 

Call:

SELECT array_agg_mult(ARRAY[ARRAY[name, id::text, url]]) AS tbl_mult_arr 
FROM tbl; 

Notiere die zusätzliche ARRAY[] Schicht, um es ein mehrdimensionales Array (2-dimenstional, um genau zu sein).

Instant-Demo:

WITH tbl(id, txt) AS (
    VALUES 
     (1::int, 'foo'::text) 
    ,(2,  'bar') 
    ,(3,  '}b",') -- txt has meta-characters 
    ) 
    , x AS (
    SELECT array_agg_mult(ARRAY[ARRAY[id::text,txt]]) AS t 
    FROM tbl 
    ) 
SELECT *, t[1][3] AS arr_element_1_1, t[3][4] AS arr_element_3_2 
FROM x; 
+0

Erstaunlich! Ich danke dir sehr! –

+1

na mein freund, du bist der sogenannte "deus ex machina" !!! – kostia

8

Sie müssen eine aggregate function verwenden; array_agg sollte tun, was Sie brauchen.

SELECT array_agg(s) FROM (SELECT name, id, url FROM the_table ORDER BY id) AS s; 
+1

Diese Antwort gibt ein Array von Datensätzen, nicht ein mehrdimensionales Array. –

+0

Ja - habe gerade im Kontext gearbeitet und du hast Recht ... Ich brauche wirklich das multidimensionale Array! –

+1

@MattW: Ich denke, dir kann geholfen werden. :) Posted eine Antwort. –