Массивы могут содержать только элементы одного типа
В вашем примере показано значение text
и integer
(без одинарных кавычек 1
). Как правило, невозможно смешивать типы в массиве. Чтобы получить эти значения в массив, вы должны создать composite type
, а затем сформировать Массив этого составного типа, как вы уже упоминали сами.
В качестве альтернативы вы можете использовать типы данных json
в Postgres 9.2+, jsonb
в Postgres 9.4+ или hstore
для пар ключ-значение.
Конечно, вы можете привести integer
к text
и работать с двумерным текстовым массивом. Рассмотрим два варианта синтаксиса для ввода массива в демонстрационном примере ниже и ознакомьтесь с руководством по вводу массива .
Есть ограничение, которое нужно преодолеть. Если вы попытаетесь объединить ARRAY (построение по ключу и значению) в двумерный массив, агрегирующая функция array_agg()
или ошибка конструктора ARRAY
:
ERROR: could not find array type for data type text[]
Хотя есть способы обойти это.
Объединить пары ключ-значение в двумерный массив
PostgreSQL 9.1 с standard_conforming_strings= on
:
CREATE TEMP TABLE tbl(
id int
,txt text
,txtarr text[]
);
Столбец txtarr
только для демонстрации вариантов синтаксиса в команде INSERT. Третий ряд украшен метасимволами:
INSERT INTO tbl VALUES
(1, 'foo', '{{1,foo1},{2,bar1},{3,baz1}}')
,(2, 'bar', ARRAY[['1','foo2'],['2','bar2'],['3','baz2']])
,(3, '}b",a{r''', '{{1,foo3},{2,bar3},{3,baz3}}'); -- txt has meta-characters
SELECT * FROM tbl;
Простой случай: объединить два целых числа (я использую одно и то же дважды) в двумерный массив int:
Обновление: лучше с пользовательской функцией агрегирования
С полиморфным типом anyarray
он работает для всех базовых типов:
CREATE AGGREGATE array_agg_mult (anyarray) (
SFUNC = array_cat
,STYPE = anyarray
,INITCOND = '{}'
);
Звоните:
SELECT array_agg_mult(ARRAY[ARRAY[id,id]]) AS x -- for int
,array_agg_mult(ARRAY[ARRAY[id::text,txt]]) AS y -- or text
FROM tbl;
Обратите внимание на дополнительный слой ARRAY[]
, чтобы сделать его многомерным массивом.
Обновление для Postgres 9.5 +
Postgres теперь поставляет вариант array_agg()
, принимающий входные данные массива, и вы можете заменить мою пользовательскую функцию сверху следующим:
Руководство:
array_agg(expression)
...
входные массивы объединяются в массив из одного
более высокое измерение (входные данные должны иметь одинаковую размерность и не могут
быть пустым или NULL)