Сега да отговоря на истинското въпрос, разкрит в коментарите, който изглежда нещо като:
Има няколко начина да се справите с това:
-
Ако и само ако масивите са с еднаква дължина, използвайте множество
unnest
функции вSELECT
клауза (отхвърлен подход, който трябва да се използва само за обратна съвместимост); -
Използвайте
generate_subscripts
за преминаване през масивите; -
Използвайте
generate_series
над подзаявки срещуarray_lower
иarray_upper
за емулиране наgenerate_subscripts
ако трябва да поддържате твърде стари версии, за да иматеgenerate_subscripts
; -
Разчитайки на реда, който
unnest
връща кортежи и се надява - като в другия ми отговор и както е показано по-долу. Ще работи, но не е гарантирано, че ще работи в бъдещи версии. -
Използвайте
WITH ORDINALITY
функционалност, добавена в PostgreSQL 9.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;
Ако масивите са с различна дължина, както е написано, той ще върне нулеви елементи за по-късия, така че работи като пълно външно съединение. Обърнете смисъла на кутията, за да получите ефект, подобен на вътрешно съединение. Функцията приема, че масивите са едномерни и че започват от индекс 1. Ако целият аргумент на масива е NULL, тогава функцията връща NULL.
По-обобщена версия ще бъде написана на PL/PgSQL и ще проверява array_ndims(a) = 1
, проверете array_lower(a, 1) = 1
, тест за нулеви масиви и т.н. Ще оставя това на вас.
Надежда за възвращаемост по двойки:
Това не е гарантирано, че работи, но работи с текущия изпълнител на заявки на 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
:
Това трябва работи, но не, защото unnest
на PostgreSQL не приема множество входни масиви (все още):
SELECT * FROM unnest(a,b);