Ora, per rispondere al reale domanda che è stata rivelata nei commenti, che sembra essere qualcosa del tipo:
Ci sono un paio di modi per affrontare questo problema:
-
Se e solo se gli array hanno la stessa lunghezza, usa più
unnestfunzioni nelSELECTclausola (un approccio deprecato che dovrebbe essere utilizzato solo per la compatibilità con le versioni precedenti); -
Usa
generate_subscriptsper scorrere gli array; -
Usa
generate_seriessu sottoquery suarray_lowerearray_upperper emularegenerate_subscriptsse devi supportare versioni troppo vecchie per averegenerate_subscripts; -
Basandosi sull'ordine che
unnestrestituisce tuple e sperando, come nell'altra mia risposta e come mostrato di seguito. Funzionerà, ma non è garantito che funzioni nelle versioni future. -
Usa il
WITH ORDINALITYfunzionalità aggiunta in PostgreSQL 9.4 (vedi anche il suo primo invio ) per ottenere un numero di riga perunnestquando esce 9.4. -
Usa più array
UNNEST, che è standard SQL ma che PostgreSQL non supporta ancora .
Quindi, supponiamo di avere la funzione arraypair con i parametri dell'array 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;
ed è invocato come:
SELECT * FROM arraypair( ARRAY[1,2,3,4,5,6,7], ARRAY['a','b','c','d','e','f','g'] );
possibili definizioni di funzione sarebbero:
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;
Produrrà risultati bizzarri e inaspettati se gli array non hanno la stessa lunghezza; vedere la documentazione sulle funzioni di ritorno degli insiemi e sul loro uso non standard in SELECT elenco per sapere perché e cosa succede esattamente.
generate_subscripts
Questa è probabilmente l'opzione più sicura:
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 gli array sono di lunghezza diversa, come scritto restituirà elementi null per il più breve, quindi funziona come un join esterno completo. Invertire il senso del caso per ottenere un effetto simile all'unione interna. La funzione presuppone che gli array siano unidimensionali e che inizino dall'indice 1. Se l'intero argomento dell'array è NULL, la funzione restituisce NULL.
Una versione più generalizzata verrebbe scritta in PL/PgSQL e verificherebbe array_ndims(a) = 1 , controlla array_lower(a, 1) = 1 , prova per array nulli, ecc. Lo lascio a te.
Sperando in ritorni a coppie:
Non è garantito che funzioni, ma funziona con l'attuale esecutore di query di 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;
Prenderei in considerazione l'utilizzo di generate_subscripts molto più sicuro.
Multi-argomento unnest :
Questo dovrebbe funziona, ma non perché unnest di PostgreSQL non accetta più array di input (ancora):
SELECT * FROM unnest(a,b);