Agora, para responder à pergunta real pergunta que foi revelada nos comentários, que parece ser algo como:
Existem algumas maneiras de lidar com isso:
-
Se e somente se as matrizes forem de tamanho igual, use váriosunnest
funções noSELECT
cláusula (uma abordagem obsoleta que deve ser usada apenas para compatibilidade com versões anteriores);
-
Usegenerate_subscripts
para fazer um loop sobre as matrizes;
-
Usegenerate_series
sobre subconsultas emarray_lower
earray_upper
para emulargenerate_subscripts
se você precisar oferecer suporte a versões muito antigas para tergenerate_subscripts
;
-
Contando com a ordem queunnest
retorna tuplas e espera - como na minha outra resposta e como mostrado abaixo. Vai funcionar, mas não é garantido que funcione em versões futuras.
-
Use oWITH ORDINALITY
funcionalidade adicionada no PostgreSQL 9.4 (veja também sua primeira postagem ) para obter um número de linha paraunnest
quando 9,4 sai.
-
UseUNNEST
de várias matrizes , que é o padrão SQL, mas que PostgreSQL ainda não suporta .
Então, digamos que temos a função
arraypair
com parâmetros de matriz a
e 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;
e é invocado como:
SELECT * FROM arraypair( ARRAY[1,2,3,4,5,6,7], ARRAY['a','b','c','d','e','f','g'] );
possíveis definições de função seriam:
SRF-in-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;
Produzirá resultados bizarros e inesperados se os arrays não forem iguais em comprimento; veja a documentação sobre funções de retorno de conjunto e seu uso não padrão no
SELECT
lista para saber por que e o que exatamente acontece. generate_subscripts
Esta é provavelmente a opção mais 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;
Se os arrays forem de comprimento desigual, conforme escrito, ele retornará elementos nulos para o menor, então funciona como uma junção externa completa. Inverta o sentido da caixa para obter um efeito de junção interna. A função assume que os arrays são unidimensionais e que começam no índice 1. Se um argumento de array inteiro for NULL, a função retornará NULL.
Uma versão mais generalizada seria escrita em PL/PgSQL e verificaria
array_ndims(a) = 1
, verifique array_lower(a, 1) = 1
, teste para matrizes nulas, etc. Vou deixar isso para você. Esperando retornos em pares:
Não é garantido que isso funcione, mas funciona com o atual executor de consultas do 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;
Eu consideraria usar
generate_subscripts
muito mais seguro. Multi-argumento unnest
:
Isso deve funciona, mas não porque o
unnest
do PostgreSQL não aceita vários arrays de entrada (ainda):SELECT * FROM unnest(a,b);