2011-07-21 73 views
14

我想要array_agg與Postgresql中的數組類型一起工作,我很難弄清楚這是否可能,如果有的話如何做到這一點。我查詢的相關部分看起來是這樣的:array_agg爲陣列類型

array_agg(ARRAY[e.alert_type::text, e.id::text, cast(extract(epoch from e.date_happened) as text)] order by e.date_happened asc, e.id asc) 

,我在響應我得到是ERROR: could not find array type for data type text[]

這是可能的,或者我應該嘗試尋找另一種方法錯誤?

謝謝!

回答

8

你可以編寫自定義的聚集來處理你的陣列的特定陣列,例如:

DROP TABLE IF EXISTS e; 
CREATE TABLE e 
(
    id serial PRIMARY KEY, 
    alert_type text, 
    date_happened timestamp with time zone 
); 

INSERT INTO e(alert_type, date_happened) VALUES 
    ('red', '2011-05-10 10:15:06'), 
    ('yellow', '2011-06-22 20:01:19'); 

CREATE OR REPLACE FUNCTION array_agg_custom_cut(anyarray) 
RETURNS anyarray 
    AS 'SELECT $1[2:array_length($1, 1)]' 
LANGUAGE SQL IMMUTABLE; 

DROP AGGREGATE IF EXISTS array_agg_custom(anyarray); 
CREATE AGGREGATE array_agg_custom(anyarray) 
(
    SFUNC = array_cat, 
    STYPE = anyarray, 
    FINALFUNC = array_agg_custom_cut, 
    INITCOND = $${{'', '', ''}}$$ 
); 

查詢:

SELECT 
    array_agg_custom(
     ARRAY[ 
      alert_type::text, 
      id::text, 
      CAST(extract(epoch FROM date_happened) AS text) 
     ]) 
FROM e; 

結果:

   array_agg_custom    
-------------------------------------------- 
{{red,1,1305036906},{yellow,2,1308787279}} 
(1 row) 

編輯:

這裏是第二較短的方式(也就是,你不需要array_agg_custom_cut功能,但是當你看到其他ARRAY水平是必要的查詢):

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

SELECT 
    array_agg_custom(
     ARRAY[ 
      ARRAY[ 
       alert_type::text, 
       id::text, 
       CAST(extract(epoch FROM date_happened) AS text) 
      ] 
     ]) 
FROM e; 

結果:

   array_agg_custom    
-------------------------------------------- 
{{red,1,1305036906},{yellow,2,1308787279}} 
(1 row) 
+0

感謝您的提示。我使用了第二種方法,除了我創建了一個新的多態函數array_append(anyarray,anyarray) - 它只是'選擇array_cat($ 1,ARRAY [$ 2])',然後使用array_append作爲我的自定義聚合函數的SFUNC。這樣,不需要外部的ARRAY []包裝,這使得用戶可見的SQL看起來更簡單。 :) – dannysauer

3

或將數組轉換爲像array_agg(array [xxx,yyy] :: text)的文本

array_agg(ARRAY[e.alert_type::text, e.id::text, 
cast(extract(epoch from e.date_happened) as text)]::text 
order by e.date_happened asc, e.id asc) 
+1

只要你使用regexp_replace()來擺脫不需要的字符,就可以作爲一種魅力。 – MarHoff