Сега да отговоря на истинското въпрос, разкрит в коментарите, който изглежда нещо като:
Има няколко начина да се справите с това:
-
Ако и само ако масивите са с еднаква дължина, използвайте множество
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);