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
unnest
funktioner iSELECT
klausul (en forældet tilgang, der kun bør bruges til bagudkompatibilitet); -
Brug
generate_subscripts
at sløjfe over arrays; -
Brug
generate_series
over underforespørgsler modarray_lower
ogarray_upper
at emuleregenerate_subscripts
hvis du skal understøtte versioner, der er for gamle til at havegenerate_subscripts
; -
Stoler på rækkefølgen, der
unnest
returnerer 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 ORDINALITY
funktionalitet tilføjet i PostgreSQL 9.4 (se også dens første opslag ) for at få et rækkenummer forunnest
nå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);