2011-07-21 10 views
14

Estoy tratando de obtener array_agg para trabajar con un tipo de matriz en Postgresql y tengo problemas para averiguar si esto es posible y, en caso afirmativo, cómo hacerlo. La parte pertinente de mi consulta es el siguiente:array_agg para tipos de matriz

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) 

El error que estoy recibiendo en respuesta es ERROR: could not find array type for data type text[]

Es esto posible o debería tratar de encontrar otro enfoque?

Gracias!

Respuesta

8

Se puede escribir de encargo agregarse para manejar su gama específica de las matrices, por ejemplo:

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 = $${{'', '', ''}}$$ 
); 

Consulta:

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

Resultado:

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

EDIT:

Aquí es segundo, camino más corto (es decir, no es necesario array_agg_custom_cut función, pero como ves ARRAY nivel adicional es necesaria en la consulta):

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; 

Resultado:

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

Gracias por la sugerencia. Utilicé el segundo enfoque, excepto que creé una nueva función polimórfica - array_append (anyarray, anyarray) - que simplemente hace 'SELECT array_cat ($ 1, ARRAY [$ 2])', y luego usa array_append como SFUNC de mi función agregada personalizada. De esta forma, el envoltorio externo ARRAY [] no es necesario, lo que hace que el SQL visible para el usuario parezca más simple. :) – dannysauer

3

o lanzar la matriz a texto como array_agg (matriz [xxx, yyy] :: texto)

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

Trabaja como un encanto siempre y cuando uses un regexp_replace() para eliminar "caracteres no deseados". No se necesita una función personalizada, así que más portátil, supongo. – MarHoff

Cuestiones relacionadas