Nyní, abychom odpověděli skutečné otázka, která byla odhalena v komentářích, která vypadá jako:
Existuje několik způsobů, jak to vyřešit:
-
Pokud a pouze v případě, že jsou pole stejně dlouhá, použijte více
unnest
funkce vSELECT
klauzule (zastaralý přístup, který by se měl používat pouze pro zpětnou kompatibilitu); -
Použijte
generate_subscripts
smyčka přes pole; -
Použijte
generate_series
přes dílčí dotazy protiarray_lower
aarray_upper
emulovatgenerate_subscripts
pokud potřebujete podporovat verze, které jsou příliš staré na to, aby mělygenerate_subscripts
; -
Spoléhání se na pořadí, které
unnest
vrací n-tice a doufá - jako v mé jiné odpovědi a jak je uvedeno níže. Bude to fungovat, ale není zaručeno, že to bude fungovat v budoucích verzích. -
Použijte
WITH ORDINALITY
funkce přidané v PostgreSQL 9.4 (viz také jeho první příspěvek ), abyste získali číslo řádku prounnest
až vyjde 9.4. -
Použijte
UNNEST
s více poli , což je standard SQL, ale který PostgreSQL zatím nepodporuje .
Řekněme tedy, že máme funkci arraypair
s parametry pole a
a 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;
a je vyvolán jako:
SELECT * FROM arraypair( ARRAY[1,2,3,4,5,6,7], ARRAY['a','b','c','d','e','f','g'] );
možné definice funkcí by byly:
SRF-in-SELECT
(zastaralé)
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;
Pokud pole nebudou mít stejnou délku, vytvoří bizarní a neočekávané výsledky; podívejte se na dokumentaci o funkcích vracení sady a jejich nestandardním použití v SELECT
seznam, abyste zjistili proč a co se přesně stalo.
generate_subscripts
Toto je pravděpodobně nejbezpečnější možnost:
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;
Pokud mají pole nestejnou délku, jak je napsáno, vrátí prvky null pro kratší, takže to funguje jako úplné vnější spojení. Obraťte smysl případu, abyste získali efekt podobný vnitřnímu spojení. Funkce předpokládá, že pole jsou jednorozměrná a že začínají na indexu 1. Pokud má celý argument pole hodnotu NULL, funkce vrátí hodnotu NULL.
Obecnější verze by byla napsána v PL/PgSQL a kontrolovala by array_ndims(a) = 1
, zkontrolujte array_lower(a, 1) = 1
, test na nulová pole atd. To nechám na vás.
Doufat v párové návraty:
Není zaručeno, že to bude fungovat, ale funguje to s aktuálním spouštěčem dotazů 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;
Zvažoval bych použití generate_subscripts
mnohem bezpečnější.
Multi-argument unnest
:
Toto by mělo funguje, ale ne, protože PostgreSQL unnest
nepřijímá více vstupních polí (zatím):
SELECT * FROM unnest(a,b);