Nun, um das Echte zu beantworten Frage, die in Kommentaren aufgedeckt wurde, die ungefähr so aussieht:
Es gibt ein paar Möglichkeiten, dies anzugehen:
-
Wenn und nur wenn die Arrays gleich lang sind, verwenden Sie mehrfaches
unnest
Funktionen imSELECT
-Klausel (ein veralteter Ansatz, der nur aus Gründen der Abwärtskompatibilität verwendet werden sollte); -
Verwenden Sie
generate_subscripts
um die Arrays zu durchlaufen; -
Verwenden Sie
generate_series
über Unterabfragen gegenarray_lower
undarray_upper
umgenerate_subscripts
zu emulieren wenn Sie Versionen unterstützen müssen, die zu alt sind, umgenerate_subscripts
zu haben; -
Verlassen Sie sich auf die Reihenfolge, die
unnest
gibt Tupel zurück und hofft - wie in meiner anderen Antwort und wie unten gezeigt. Es wird funktionieren, aber es ist nicht garantiert, dass es in zukünftigen Versionen funktioniert. -
Verwenden Sie den
WITH ORDINALITY
Funktionalität in PostgreSQL 9.4 hinzugefügt (siehe auch sein erstes Posting ). ), um eine Zeilennummer fürunnest
zu erhalten wenn 9.4 herauskommt. -
Verwenden Sie
UNNEST
mit mehreren Arrays , der SQL-Standard ist, aber der PostgreSQL wird noch nicht unterstützt .
Angenommen, wir haben die Funktion arraypair
mit Arrayparametern a
und 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;
und es wird aufgerufen als:
SELECT * FROM arraypair( ARRAY[1,2,3,4,5,6,7], ARRAY['a','b','c','d','e','f','g'] );
mögliche Funktionsdefinitionen wären:
SRF-in-SELECT
(veraltet)
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;
Führt zu bizarren und unerwarteten Ergebnissen, wenn die Arrays nicht gleich lang sind; siehe die Dokumentation zu Satzrückgabefunktionen und ihrer nicht standardmäßigen Verwendung in SELECT
Liste, um zu erfahren, warum und was genau passiert.
generate_subscripts
Dies ist wahrscheinlich die sicherste Option:
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;
Wenn die Arrays von ungleicher Länge sind, werden wie geschrieben Null-Elemente für die kürzeren zurückgegeben, sodass es wie ein vollständiger äußerer Join funktioniert. Kehren Sie den Sinn des Falls um, um einen Inner-Join-ähnlichen Effekt zu erzielen. Die Funktion geht davon aus, dass die Arrays eindimensional sind und bei Index 1 beginnen. Wenn ein gesamtes Array-Argument NULL ist, gibt die Funktion NULL zurück.
Eine allgemeinere Version wäre in PL/PgSQL geschrieben und würde array_ndims(a) = 1
prüfen , überprüfen Sie array_lower(a, 1) = 1
, auf Null-Arrays testen usw. Das überlasse ich Ihnen.
Hoffnung auf paarweise Renditen:
Das funktioniert nicht garantiert, aber mit dem aktuellen Abfrage-Executor von 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;
Ich würde die Verwendung von generate_subscripts
in Betracht ziehen viel sicherer.
Mehrere Argumente unnest
:
Das sollte funktioniert, tut es aber nicht, weil PostgreSQL unnest
akzeptiert (noch) nicht mehrere Eingabe-Arrays:
SELECT * FROM unnest(a,b);