Postgres 9.3 and later
Simple zip ()
Consider the following demo for Postgres 9.3 or earlier :
SELECT ARRAY[a,b] AS ab FROM ( SELECT unnest('{a,b,c}'::text[]) AS a ,unnest('{d,e,f}'::text[]) AS b ) x;
Result:
ab
Note that both arrays must have the same number of elements for parallel printing, or instead you get a cross-connection.
You can wrap this in a function if you want:
CREATE OR REPLACE FUNCTION zip(anyarray, anyarray) RETURNS SETOF anyarray LANGUAGE SQL AS $func$ SELECT ARRAY[a,b] FROM (SELECT unnest($1) AS a, unnest($2) AS b) x; $func$;
Call:
SELECT zip('{a,b,c}'::text[],'{d,e,f}'::text[]);
The same result.
zip () for a multidimensional array:
Now, if you want to fill this new set of arrays into a single 2-dimenstional array, it becomes more complex.
SELECT ARRAY (SELECT ...)
or
SELECT array_agg(ARRAY[a,b]) AS ab FROM ( SELECT unnest('{a,b,c}'::text[]) AS a ,unnest('{d,e,f}'::text[]) AS b ) x
or
SELECT array_agg(ARRAY[ARRAY[a,b]]) AS ab FROM ...
will result in the same error message (checked with pg 9.1.5):
ERROR: could not find array type for data type text []
But there is a way around this, as we developed into this close question .
Create a custom aggregation function:
CREATE AGGREGATE array_agg_mult (anyarray) ( SFUNC = array_cat ,STYPE = anyarray ,INITCOND = '{}' );
And use it as follows:
SELECT array_agg_mult(ARRAY[ARRAY[a,b]]) AS ab FROM ( SELECT unnest('{a,b,c}'::text[]) AS a ,unnest('{d,e,f}'::text[]) AS b ) x
Result:
{{a,d},{b,e},{c,f}}
Pay attention to the additional layer ARRAY[] ! Without it, and simply:
SELECT array_agg_mult(ARRAY[a,b]) AS ab FROM ...
You get:
{a,d,b,e,c,f}
What may be useful for other purposes.
Reset another function:
CREATE OR REPLACE FUNCTION zip2(anyarray, anyarray) RETURNS SETOF anyarray LANGUAGE SQL AS $func$ SELECT array_agg_mult(ARRAY[ARRAY[a,b]]) FROM (SELECT unnest($1) AS a, unnest($2) AS b) x; $func$;
Call:
SELECT zip2('{a,b,c}'::text[],'{d,e,f}'::text[]); -- or any other array type
Result:
{{a,d},{b,e},{c,f}}
Postgres 9.4 +
Use the ROWS FROM construct or the updated unnest() , which parallelizes multiple arrays. Each of them can have a different length. You get ( for the documentation ):
[...] the number of rows of the result in this case is the number of the largest function, the result with smaller results, supplemented by zero values ββthat will correspond.
Use this cleaner and simpler option:
SELECT ARRAY[a,b] AS ab FROM unnest('{a,b,c}'::text[] , '{d,e,f}'::text[]) x(a,b);
Postgres 9.5 +
sends array_agg(array expression) :
Function Argument Type(s) Return Type array_agg(expression) any array type same as argument data type Description input arrays concatenated into array of one higher dimension (inputs must all have same dimensionality, and cannot be empty or NULL)
This is a replacement for my custom aggregate function array_agg_mult() , implemented in C, which is much faster. Use it.