For nu at besvare det rigtige spørgsmål, der blev afsløret i kommentarer, som ser ud til at være noget i stil med:
Der er et par måder at tackle dette på:
-
Hvis og kun hvis arrays er lige lange, skal du bruge flere
unnestfunktioner iSELECTklausul (en forældet tilgang, der kun bør bruges til bagudkompatibilitet); -
Brug
generate_subscriptsat sløjfe over arrays; -
Brug
generate_seriesover underforespørgsler modarray_lowerogarray_upperat emuleregenerate_subscriptshvis du skal understøtte versioner, der er for gamle til at havegenerate_subscripts; -
Stoler på rækkefølgen, der
unnestreturnerer tuples i og håbe - ligesom i mit andet svar og som vist nedenfor. Det vil virke, men det er ikke garanteret, at det virker i fremtidige versioner. -
Brug
WITH ORDINALITYfunktionalitet tilføjet i PostgreSQL 9.4 (se også dens første opslag ) for at få et rækkenummer forunnestnår 9.4 kommer ud. -
Brug multiple-array
UNNEST, som er SQL-standard, men hvilket PostgreSQL understøtter ikke endnu .
Så lad os sige, at vi har funktionen arraypair med array-parametre a og 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;
og det kaldes som:
SELECT * FROM arraypair( ARRAY[1,2,3,4,5,6,7], ARRAY['a','b','c','d','e','f','g'] );
mulige funktionsdefinitioner ville være:
SRF-in-SELECT (forældet)
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;
Vil producere bizarre og uventede resultater, hvis arrays ikke er lige lange; se dokumentationen om sæt returnerende funktioner og deres ikke-standard brug i SELECT liste for at lære hvorfor, og hvad der præcist sker.
generate_subscripts
Dette er sandsynligvis den sikreste mulighed:
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;
Hvis arrays er af forskellig længde, vil det som skrevet returnere nul-elementer for de kortere, så det fungerer som en fuld ydre joinforbindelse. Vend sagens forstand for at få en indre-sammenføjningslignende effekt. Funktionen antager, at arrays er endimensionelle, og at de starter ved indeks 1. Hvis et helt array-argument er NULL, returnerer funktionen NULL.
En mere generaliseret version ville blive skrevet i PL/PgSQL og ville kontrollere array_ndims(a) = 1 , tjek array_lower(a, 1) = 1 , test for nul-arrays osv. Jeg overlader det til dig.
Håber på parvise afkast:
Dette er ikke garanteret at virke, men gør det med PostgreSQL's nuværende forespørgselseksekutor:
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;
Jeg ville overveje at bruge generate_subscripts meget sikrere.
Multi-argument unnest :
Dette skal virker, men gør det ikke fordi PostgreSQL's unnest accepterer ikke flere input-arrays (endnu):
SELECT * FROM unnest(a,b);