För att nu svara på det riktiga fråga som avslöjades i kommentarer, som verkar vara något i stil med:
Det finns ett par sätt att tackla detta:
-
Om och bara om arrayerna är lika långa, använd flera
unnest
funktioner iSELECT
klausul (en föråldrad metod som endast bör användas för bakåtkompatibilitet); -
Använd
generate_subscripts
att loopa över arrayerna; -
Använd
generate_series
över delfrågor motarray_lower
ocharray_upper
för att emuleragenerate_subscripts
om du behöver stödja versioner som är för gamla för att hagenerate_subscripts
; -
Förlitar sig på ordern som
unnest
returnerar tuples in och hoppas - som i mitt andra svar och som visas nedan. Det kommer att fungera, men det är inte garanterat att det fungerar i framtida versioner. -
Använd den
WITH ORDINALITY
funktionalitet tillagd i PostgreSQL 9.4 (se även dess första inlägg ) för att få ett radnummer förunnest
när 9.4 kommer ut. -
Använd
UNNEST
med flera arrayer , som är SQL-standard men vilket PostgreSQL stöder inte ännu .
Så säg att vi har funktionen arraypair
med arrayparametrar a
och 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;
och det anropas som:
SELECT * FROM arraypair( ARRAY[1,2,3,4,5,6,7], ARRAY['a','b','c','d','e','f','g'] );
möjliga funktionsdefinitioner skulle vara:
SRF-in-SELECT
(utfasad)
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;
Kommer att ge bisarra och oväntade resultat om arrayerna inte är lika långa; se dokumentationen om uppsättningsreturfunktioner och deras icke-standardiserade användning i SELECT
lista för att lära dig varför och vad som händer exakt.
generate_subscripts
Detta är förmodligen det säkraste alternativet:
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;
Om arrayerna är av olika längd, som skrivet, kommer det att returnera nollelement för det kortare, så det fungerar som en fullständig yttre koppling. Vänd om känslan av fallet för att få en inre sammanfogningsliknande effekt. Funktionen antar att arrayerna är endimensionella och att de börjar vid index 1. Om ett helt arrayargument är NULL returnerar funktionen NULL.
En mer generaliserad version skulle skrivas i PL/PgSQL och skulle kontrollera array_ndims(a) = 1
, kontrollera array_lower(a, 1) = 1
, testa för nollmatriser, etc. Jag överlåter det till dig.
Hoppas på parvis avkastning:
Det här fungerar inte garanterat, men det gör det med PostgreSQL:s nuvarande frågeexekutor:
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;
Jag skulle överväga att använda generate_subscripts
mycket säkrare.
Multi-argument unnest
:
Detta bör fungerar, men gör det inte eftersom PostgreSQL:s unnest
accepterar inte flera inmatningsmatriser (ännu):
SELECT * FROM unnest(a,b);