2014-03-27 5 views

Antwort

18

Sie könnten unnest verwenden, um die Felder zu öffnen und dann array_agg sie zusammen zu setzen:

select array_agg(c) 
from (
    select unnest(column_name) 
    from table_name 
) as dt(c); 
+1

Wahrscheinlich viel effizienter als meins, aber wird nicht unbedingt die Reihenfolge beibehalten; Sie müssten dafür "mit Ordinalität" verwenden. –

+0

@Craig: Welche Version von PostgreSQL hat MIT ORDINALITÄT? Wie auch immer, benutzerdefinierte Aggregate sind irgendwie cool –

+0

Hinzugefügt in PostgreSQL 9.4, also "in Kürze". Ich bin zu sehr daran gewöhnt, mit git master zu arbeiten ... –

0

Der einzige Weg, dies zu tun ist in einer Funktion:

CREATE FUNCTION merge_arrays() RETURNS int[] AS $$ 
DECLARE 
    this record; 
    res int[]; 
BEGIN 
    FOR this IN 
    SELECT column_name FROM table_name 
    LOOP 
    array_cat(res, this.column_name); 
    END LOOP; 
    RETURN res; 
END; $$ LANGUAGE plpgsql; 

Dann können Sie

SELECT merge_arrays(); 

das Ergebnis zu erhalten, für den Sie suchen.

Dies codiert natürlich Ihre Tabellendefinition in die Funktion, was ein Problem sein kann (oder auch nicht). Außerdem können Sie eine WHERE-Klausel in die Schleifenabfrage einfügen, um die Datensätze einzuschränken, deren Arrays Sie anhängen möchten. Sie können dazu einen zusätzlichen Funktionsparameter verwenden.

Denken Sie daran, dass Sie möglicherweise ein sehr großes Array erhalten, wenn Ihre Tabelle größer wird und die Leistung beeinträchtigen kann. Benötigen Sie wirklich alle Sub-Arrays aus allen Records in einem großen Array? Sehen Sie sich Ihre Anwendung an und prüfen Sie, ob Sie die Zusammenführung auf dieser Ebene statt in einer einzelnen Abfrage durchführen können.

8

definiert ein triviales benutzerdefiniertes Aggregat:

CREATE AGGREGATE array_cat_agg(anyarray) (
    SFUNC=array_cat, 
    STYPE=anyarray 
); 

und verwendet es:

WITH v(a) AS (VALUES (ARRAY[1,2,3]), (ARRAY[4,5,6,7])) 
SELECT array_cat_agg(a) FROM v; 

Wenn Sie einen bestimmten Auftrag wünschen, setzen Sie es innerhalb des Aggregats Anruf, dh array_cat_agg(a ORDER BY ...)

Dies ist ungefähr O(n log n) für n Reihen (denke ich). Für eine bessere Leistung müssen Sie es in C schreiben, wo Sie die effizientere (aber fürchterliche) C-API für PostgreSQL-Arrays verwenden können, um zu vermeiden, dass das Array bei jeder Iteration erneut kopiert wird.

+0

Nizza, einfach und auf den Punkt. – Urkle

Verwandte Themen