Объединение двух массивов в PostgreSQL без unnesting
у меня есть два массива в PostgreSQL, которые мне нужно объединить. Например:
{1,2,3}
Союз {1,4,5}
вернутся {1,2,3,4,5}
использование оператора concatenate ( | | ) не удаляет повторяющиеся записи, т. е. возвращает {1,2,3,1,4,5}
я нашел одно решение в интернете, однако мне не нравится, как нужно отменить оба массива:
select ARRAY(select unnest(ARRAY[1,2,3]) as a UNION select unnest(ARRAY[2,3,4,5]) as a)
есть ли оператор или встроенная функция, которая будет чисто объединять два массива?
3 ответов
Если ваша проблема в unnest дважды, это будет unnest только один раз
select array_agg(a order by a)
from (
select distinct unnest(array[1,2,3] || array[2,3,4,5]) as a
) s;
есть расширение intarray с (в пакете contrib), который содержит некоторые полезные функции и операторы:
postgres=# create extension intarray ;
CREATE EXTENSION
с одиночным оператором трубы:
postgres=# select array[1,2,3] | array[3,4,5];
?column?
─────────────
{1,2,3,4,5}
(1 row)
или :
postgres=# select uniq(ARRAY[1,2,3] || ARRAY[3,4,5]);
uniq
─────────────
{1,2,3,4,5}
(1 row)
ANSI/SQL знает multiset, но он еще не поддерживается PostgreSQL.
можно сделать так...
select uniq(sort(array_remove(array_cat(ARRAY[1,2,3], ARRAY[1,4,5]), NULL)))
выдает:
{1,2,3,4,5}
array_remove необходим, потому что вы не можете сортировать массивы с нулями.
Сортировка необходима, потому что uniq
де-дублирует, только если найдены смежные элементы.
преимущество этого подхода над @Clodoaldo Neto заключается в том, что он работает целиком в select и не является unnest в предложении FROM. Это делает его простым для работы с несколькими столбцами массивов одновременно и в одном сканирование таблицы. (Хотя см. версию Ryan Guill как функцию в комментарии).
кроме того, этот шаблон работает для всех типов массивов (элементы who сортируются).
недостатком является то, что, возможно, его немного медленнее для более длинных массивов (из-за сортировки и 3 промежуточных распределений массива).
Я думаю, что и это, и ответ accept не удастся, если вы хотите сохранить NULL в результате.