2014-03-27 33 views

回答

18

你可以使用unnest開拓陣列,然後array_agg把他們重新走到一起:

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

可能比我的效率高很多,但不一定會保留元素順序;你必須爲此使用'與通常'。 –

+0

@Craig:哪個版本的PostgreSQL具有ORDINALITY?無論如何,定製的聚合是有點酷' –

+0

添加在PostgreSQL 9.4,所以「即將推出」。我太習慣使用git master ... –

0

你可以做到這一點的唯一方法是在函數內部:

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; 

然後你可以

SELECT merge_arrays(); 

得到你正在尋找的結果。

這當然硬編碼您的表定義到函數,這可能(或可能不)是一個問題。此外,您可能希望在循環查詢中放置WHERE子句以限制要附加其數組的記錄;你可以使用一個附加的函數參數來做到這一點。

請記住,隨着表的大小增加並且可能會影響性能,可能會得到一個非常大的數組。你真的需要一個大陣列中所有記錄的所有子陣列嗎?查看您的應用程序,看看您是否可以在該級別進行合併,而不是在單個查詢中進行合併。

8

定義一個簡單的自定義聚合:

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

,並使用它:

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

如果你想要一個特定的順序,把它彙總調用內,即array_cat_agg(a ORDER BY ...)

這是大約O(n log n) n行(我認爲)。爲了獲得更好的性能,你需要用C語言編寫它,在那裏你可以使用更高效(但可怕的)使用的C API用於PostgreSQL數組,以避免在每次迭代時重新複製數組。

+0

好的,簡單,和對點。 – Urkle

相關問題