さて、本物に答える コメントで明らかにされた質問。これは次のように見えます:
これに取り組むにはいくつかの方法があります:
-
配列の長さが等しい場合にのみ、複数の
unnest
を使用しますSELECT
の関数 句(下位互換性のためにのみ使用する必要がある非推奨のアプローチ); -
generate_subscripts
を使用します 配列をループする; -
generate_series
を使用しますarray_lower
に対するサブクエリ およびarray_upper
generate_subscripts
をエミュレートしますgenerate_subscripts
を使用するには古すぎるバージョンをサポートする必要がある場合; -
unnest
の順序に依存する 私の他の回答のように、そして以下に示すように、タプルを返し、期待しています。動作しますが、将来のバージョンで動作することは保証されていません。 -
WITH ORDINALITY
を使用します PostgreSQL9.4で追加された機能 (最初の投稿 も参照してください。 )unnest
の行番号を取得します 9.4が出たとき。 -
複数配列の
UNNEST
を使用する 、これはSQL標準ですが、どのPostgreSQLですまだサポートしていません 。
したがって、関数arraypair
があるとします。 配列パラメータ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;
そしてそれは次のように呼び出されます:
SELECT * FROM arraypair( ARRAY[1,2,3,4,5,6,7], ARRAY['a','b','c','d','e','f','g'] );
可能な関数定義は次のとおりです。
SRF-in- SELECT
(非推奨)
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;
配列の長さが等しくない場合、奇妙で予期しない結果が生成されます。 SELECT
の集合戻り関数とその非標準使用に関するドキュメントを参照してください。 理由と正確に何が起こるかを学ぶためのリスト。
generate_subscripts
これはおそらく最も安全なオプションです:
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;
配列の長さが等しくない場合、記述されているように、短い方の配列はnull要素を返すため、完全な外部結合のように機能します。ケースの感覚を逆にして、内部結合のような効果を得る。この関数は、配列が1次元であり、インデックス1から始まることを前提としています。配列引数全体がNULLの場合、関数はNULLを返します。
より一般化されたバージョンはPL/PgSQLで記述され、array_ndims(a) = 1
をチェックします。 、array_lower(a, 1) = 1
を確認してください 、null配列のテストなど。それはあなたにお任せします。
ペアワイズリターンの希望:
これは動作が保証されていませんが、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;
generate_subscripts
の使用を検討します はるかに安全です。
マルチ引数unnest
:
これはすべき 動作しますが、PostgreSQLのunnest
が原因で動作しません (まだ)複数の入力配列を受け入れません:
SELECT * FROM unnest(a,b);