Ahora, para responder a la real pregunta que se reveló en los comentarios, que parece ser algo como:
Hay un par de maneras de abordar esto:
-
Si y solo si las matrices tienen la misma longitud, use múltiples
unnest
funciones en elSELECT
cláusula (un enfoque obsoleto que solo debe usarse para la compatibilidad con versiones anteriores); -
Utilice
generate_subscripts
para recorrer las matrices; -
Usa
generate_series
sobre subconsultas contraarray_lower
yarray_upper
para emulargenerate_subscripts
si necesita admitir versiones demasiado antiguas para tenergenerate_subscripts
; -
Confiando en el orden que
unnest
devuelve tuplas y espera, como en mi otra respuesta y como se muestra a continuación. Funcionará, pero no se garantiza que funcione en futuras versiones. -
Usa el
WITH ORDINALITY
funcionalidad añadida en PostgreSQL 9.4 (ver también su primera publicación ) para obtener un número de fila paraunnest
cuando sale 9.4. -
Usar matriz múltiple
UNNEST
, que es estándar SQL pero que PostgreSQL no es compatible todavía .
Entonces, digamos que tenemos la función arraypair
con parámetros de matriz a
y b
:
CREATE OR REPLACE FUNCTION arraypair (a integer[], b text[])
RETURNS TABLE (col_a integer, col_b text) AS $$
-- blah code here blah
$$ LANGUAGE whatever IMMUTABLE;
y se invoca como:
SELECT * FROM arraypair( ARRAY[1,2,3,4,5,6,7], ARRAY['a','b','c','d','e','f','g'] );
posibles definiciones de función serían:
SRF-en-SELECT
(obsoleto)
CREATE OR REPLACE FUNCTION arraypair (a integer[], b text[])
RETURNS TABLE (col_a integer, col_b text) AS $$
SELECT unnest(a), unnest(b);
$$ LANGUAGE sql IMMUTABLE;
Producirá resultados extraños e inesperados si las matrices no tienen la misma longitud; consulte la documentación sobre las funciones de devolución de conjuntos y su uso no estándar en SELECT
lista para saber por qué y qué sucede exactamente.
generate_subscripts
Esta es probablemente la opción más segura:
CREATE OR REPLACE FUNCTION arraypair (a integer[], b text[])
RETURNS TABLE (col_a integer, col_b text) AS $$
SELECT
a[i], b[i]
FROM generate_subscripts(CASE WHEN array_length(a,1) >= array_length(b,1) THEN a::text[] ELSE b::text[] END, 1) i;
$$ LANGUAGE sql IMMUTABLE;
Si las matrices tienen una longitud desigual, como está escrito, devolverá elementos nulos para el más corto, por lo que funciona como una combinación externa completa. Invierta el sentido del caso para obtener un efecto similar al de unión interna. La función asume que las matrices son unidimensionales y que comienzan en el índice 1. Si el argumento de una matriz completa es NULL, la función devuelve NULL.
Una versión más generalizada estaría escrita en PL/PgSQL y verificaría array_ndims(a) = 1
, marque array_lower(a, 1) = 1
, probar matrices nulas, etc. Te lo dejo a ti.
Esperando retornos por parejas:
No se garantiza que funcione, pero funciona con el ejecutor de consultas actual de PostgreSQL:
CREATE OR REPLACE FUNCTION arraypair (a integer[], b text[])
RETURNS TABLE (col_a integer, col_b text) AS $$
WITH
rn_c1(rn, col) AS (
SELECT row_number() OVER (), c1.col
FROM unnest(a) c1(col)
),
rn_c2(rn, col) AS (
SELECT row_number() OVER (), c2.col
FROM unnest(b) c2(col)
)
SELECT
rn_c1.col AS c1,
rn_c2.col AS c2
FROM rn_c1
INNER JOIN rn_c2 ON (rn_c1.rn = rn_c2.rn);
$$ LANGUAGE sql IMMUTABLE;
Consideraría usar generate_subscripts
mucho más seguro.
Multi-argumento unnest
:
Esto debería funciona, pero no porque unnest
de PostgreSQL no acepta múltiples matrices de entrada (todavía):
SELECT * FROM unnest(a,b);