I'm trying to get array_agg
to work with an array type in Postgresql and I'm having trouble figuring out if this is possible and if so how to do it. The pertinent part of my query looks like this:
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)
The error that I'm getting in response is ERROR: could not find array type for data type text[]
Is this possible or should I try to find another approach?
Thanks!
PostgreSQL – ARRAY_AGG() Function It specifies the order of rows that are processed in the collection, which establishes the order of the elements in the result array. It is often used with the GROUP BY clause.
The ARRAY_AGG() accepts an expression that returns a value of any type which is valid for an array element. The ORDER BY clause is an optional clause. It specifies the order of rows processed in the aggregation, which determines the order of the elements in the result array.
Define arrays as SQL variables. Use the ARRAY_AGG built-in function in a cursor declaration, to assign the rows of a single-column result table to elements of an array. Use the cursor to retrieve the array into an SQL out parameter. Use an array constructor to initialize an array.
You could write custom aggregate to handle your specific array of arrays, e.g.:
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 = $${{'', '', ''}}$$
);
Query:
SELECT
array_agg_custom(
ARRAY[
alert_type::text,
id::text,
CAST(extract(epoch FROM date_happened) AS text)
])
FROM e;
Result:
array_agg_custom
--------------------------------------------
{{red,1,1305036906},{yellow,2,1308787279}}
(1 row)
EDIT:
Here is second, shorter way (that is, you don't need array_agg_custom_cut
function, but as you see additional ARRAY
level is necessary in query):
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;
Result:
array_agg_custom
--------------------------------------------
{{red,1,1305036906},{yellow,2,1308787279}}
(1 row)
or cast the array to text like 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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With