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ù
unnest
funzioni nelSELECT
clausola (un approccio deprecato che dovrebbe essere utilizzato solo per la compatibilità con le versioni precedenti); -
Usa
generate_subscripts
per scorrere gli array; -
Usa
generate_series
su sottoquery suarray_lower
earray_upper
per emularegenerate_subscripts
se devi supportare versioni troppo vecchie per averegenerate_subscripts
; -
Basandosi sull'ordine che
unnest
restituisce 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 ORDINALITY
funzionalità aggiunta in PostgreSQL 9.4 (vedi anche il suo primo invio ) per ottenere un numero di riga perunnest
quando 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);