intarray
Функции и операторы для работы с массивами целых чисел без NULL.
Схема размещения:
ext
.Модуль предоставляет несколько полезных функций и операторов для работы с одномерными целочисленными массивами (
1-D integer arrays
). Если в массиве присутствует значение NULL
, операция выдаст ошибку. Также поддерживается поиск по индексу для ряда операторов.Модуль поддерживает проверку равенства массивов, а также индексы для операторов:
&&
– пересечение;@>
– левый содержит правый;<@
– правый содержит левый;@@
,~~
– соответствие запросу.
Операторы
&&
, @>
и <@
работают только с не содержащими NULL
целочисленными массивами. Благодаря этому ограничению, в большинстве случаев они работают быстрее, чем равнозначные одноименные встроенные операторы PostgreSQL, которые работают с массивами любых типов.Операторы
@@
и ~~
проверяют, удовлетворяет ли массив запросу, представляемому в виде значения специализированного типа данных query_int
. Запрос содержит целочисленные значения, возможно с использованием операторов &
(AND
), |
(OR
) и !
(NOT
). Например, запросу 1&(2|3)
удовлетворяют массивы, которые содержат 1
и также содержат 2
или 3
.Выражение запроса заключается в одинарные кавычки (апострофы). Пример:
'1&(2|3)'
.Функция | Входные параметры | Возвращаемое значение | Описание |
---|---|---|---|
icount | integer[] | integer | Выдает число элементов в массиве |
sort | integer[], dir text | integer[] | Сортирует массив в порядке возрастания или убывания в зависимости от значения параметра dir : asc – по возрастанию или desc – по убыванию |
sort | integer[] | integer[] | Сортирует в порядке возрастания |
sort_asc | integer[] | integer[] | Сортирует в порядке возрастания |
sort_desc | integer[] | integer[] | Сортирует в порядке убывания |
uniq | integer[] | integer[] | Удаляет стоящие рядом дубликаты |
idx | integer[], item integer | integer | Возвращает порядковый номер (индекс) первого равного значению item элемента массива или 0 в случае отсутствия элемента со значением item |
subarray | integer[], start integer [, len integer ] | integer[] | Извлекает часть массива, которая начинается с позиции start и содержит len элементов; параметр len можно опустить, тогда будет извлечена часть массива, которая начинается с позиции start и до конца |
intset | integer | integer[] | Создает массив с одним элементом |
Оператор | Возвращаемое значение | Описание | Примечание |
---|---|---|---|
integer[] && integer[] | boolean | Пересекаются ли массивы; true – имеется минимум один общий элемент | – |
integer[] @> integer[] | boolean | Правый массив содержится в левом | – |
integer[] <@ integer[] | boolean | Левый массив содержится в правом | – |
# integer[] | integer | Возвращает число элементов в массиве | Аналогичная функция – icount |
integer[] # integer | integer | Возвращает индекс первого элемента, равного правому аргументу, или 0 , если такого элемента нет | Аналогичная функция – idx |
integer[] + [integer | integer[]] | integer[] | Соединение: добавляет элемент в конец массива или соединяет два массива | В качестве правого аргумента может быть целое число или массив |
integer[] - [integer | integer[]] | integer[] | Вычитание: удаляет элемент из массива или из левого массива удаляет элементы правого массива | В качестве правого аргумента может быть целое число или массив |
integer[] | [integer | integer[]] | integer[] | Вычисляет объединение аргументов | В качестве правого аргумента может быть целое число или массив |
integer[] & integer[] | integer[] | Вычисляет пересечение аргументов | – |
integer[] @@ query_int | boolean | Удовлетворяет ли массив запросу; запрос представлен в виде значения специализированного типа данных query_int | Пример: запросу 1&(2|3) удовлетворяют запросы, которые содержат 1 И также содержат 2 ИЛИ 3 |
query_int ~~ integer[] | boolean | Удовлетворяет ли массив запросу; коммутирующий оператор к @@ ; запрос представлен в виде значения специализированного типа данных query_int | Запрос содержит целочисленные значения, сравниваемые с элементами массива, возможно с использованием операторов & (AND ), | (OR ) и ! (NOT ) |
Модуль поддерживает индексы для операторов
&&
, @>
, <@
и @@
, а также проверку равенства массивов.Модуль предоставляет два параметризованных класса операторов
GiST
:-
gist__int_ops
(используется по умолчанию) подходит для небольших по размеру наборов данных (массивов); этот класс аппроксимирует набор целых чисел в виде массива диапазонов; в его параметреnumranges
можно задать максимальное число диапазонов в одном ключе индекса (параметр необязательный, целочисленный и может принимать значения от1
до253
, по умолчанию равен100
); при увеличении числа составляющих ключ индексаGiST
массивов поиск работает точнее из-за того, что сканируется меньшая область в индексе и меньше страниц массива, но сам индекс при этом становится больше; -
gist__intbig_ops
применяет сигнатуру большего размера и подходит для индексации больших наборов данных (массивов), то есть содержащих много различных значений массива столбцов; этот класс аппроксимирует набор целых чисел в виде сигнатуры битовой карты; в его параметреsiglen
можно задать размер сигнатуры в байтах (параметр необязательный, целочисленный и может принимать значения от1
до2024
, по умолчанию равен16
); при увеличении размера сигнатуры поиск работает точнее из-за того, что сканируется меньшая область в индексе и меньше страниц массива, но сам индекс становится больше; -
gin__int_ops
– нестандартный класс операторовGIN
, поддерживающий те же операторы.
Значения массива можно вводить разными способами, которые являются идентичными:
'{1,2,3,5}'::integer[]
;array [1,2,3,5]
.
В примерах будут использоваться оба способа.
Функции:
-
icount
:SELECT icount('{1,223,303,5,33}'::integer[]);
Другой способ представления массива:SELECT icount(array [1,223,303,5,33]);
Пример вывода:Раскрыть type=sqlicount -------- 5 (1 row)
-
sort
:Пример в порядке убывания:SELECT sort('{1,223,303,5,33}'::integer[], 'desc');
Пример вывода:Раскрыть type=sqlsort ------------------ {303,223,33,5,1} (1 row)
Пример в порядке возрастания без параметраdir
:SELECT sort(array[1,223,303,5,33]);
Пример вывода:Раскрыть type=sqlsort ------------------ {1,5,33,223,303} (1 row)
-
sort_asc
:SELECT sort_asc (array[1,223,303,5,33]);
Пример вывода:Раскрыть type=sqlsort_asc ------------------ {1,5,33,223,303} (1 row)
-
sort_desc
:SELECT sort_desc (array[1,223,303,5,33]);
Пример вывода:Раскрыть type=sqlsort_desc ------------------ {303,223,33,5,1} (1 row)
-
uniq
:SELECT uniq('{1,1,223,303,5,5,332,2,2,2,3,1,1}'::integer[]);
Пример вывода:Раскрыть type=sqluniq ------------------------- {1,223,303,5,332,2,3,1} (1 row)
Использование в сочетании с функциейsort
для удаления всех дубликатов:SELECT uniq(sort('{1,1,1,223,303,5,5,332,2,2,2,3,1,1}'::integer[]));
Пример вывода:Раскрыть type=sqluniq ----------------------- {1,2,3,5,223,303,332} (1 row)
-
idx
:Элемент со значениемitem
присутствует в массиве:SELECT idx(array[1,223,303,5,33], 5);
Пример вывода:Раскрыть type=sqlidx ----- 4 (1 row)
Элемента со значениемitem
нет в массиве:SELECT idx(array[1,223,303,5,33], 6);
Пример вывода:Раскрыть type=sqlidx ----- 0 (1 row)
-
subarray
:Извлечение части массива, начиная с позиции3
длиной в4
элемента:SELECT subarray('{1,2,3,4,5,4,3}'::integer[], 3, 4);
Пример вывода:Раскрыть type=sqlsubarray ----------- {3,4,5,4} (1 row)
Применение функции без указания параметра длины извлекаемой части массиваlen
:SELECT subarray('{1,2,3,4,5,4,3}'::integer[], 3);
Пример вывода:Раскрыть type=sqlsubarray ----------- {3,4,5,4,3} (1 row)
-
intset
:SELECT intset(233);
Пример вывода:Раскрыть type=sqlintset -------- {233} (1 row)
-
пересечение:
-
Есть пересечение:
SELECT '{1,2,3,4,5,4,3}'::integer[] && '{1,4,6}'::integer[];
Пример вывода:Раскрыть type=sql?column? ---------- t (1 row)
-
Нет пересечения:
SELECT '{1,2,3,4,5,4,3}'::integer[] && '{12,33}'::integer[];
Пример вывода:Раскрыть type=sql?column? ---------- f (1 row)
-
-
содержание одного массива в другом:
-
правый массив содержится в левом:
SELECT '{1,2,3,4,5,4,3}'::integer[] @> '{4,5,4}'::integer[];
Пример вывода:Раскрыть type=sql?column? ---------- t (1 row)
-
левый массив содержится в правом:
SELECT '{2,3,8}'::integer[] <@ '{1,2,3,4,5,4,3}'::integer[];
Пример вывода:Раскрыть type=sql?column? ---------- f (1 row)
-
-
добавление элемента в конец массива:
SELECT '{14,54}'::integer[] + 34;
Пример вывода:Раскрыть type=sql?column? ------------ {14,54,34} (1 row)
-
соединение двух массивов:
SELECT '{14,54}'::integer[] + '{2,3,8}'::integer[];
Пример вывода:Раскрыть type=sql?column? --------------- {14,54,2,3,8} (1 row)
-
удаление элемента из массива:
SELECT '{14,54,34}'::integer[] - 54;
Пример вывода:Раскрыть type=sql?column? ---------- {14,34} (1 row)
-
удаление элементов правого массива из левого:
SELECT '{2,2,18,3,3,66,3}'::integer[] - '{2,3,8}'::integer[];
Пример вывода:Раскрыть type=sql?column? ---------- {18,66} (1 row)
-
объединение аргументов:
-
объединение с элементом:
SELECT array[2,4,8,66] | 55;
Пример вывода:Раскрыть type=sql?column? --------------- {2,4,8,55,66} (1 row)
-
объединение с массивом:
SELECT array[2,4,8,66] | array[1,3,55];
Пример вывода:Раскрыть type=sql?column? ------------------- {1,2,3,4,8,55,66} (1 row)
-
-
пересечение аргументов:
SELECT '{2,18,3,66}'::integer[] & '{2,3,8}'::integer[];
Пример вывода:Раскрыть type=sql?column? ---------- {2,3} (1 row)
-
соответствие запросу:
-
проверка по запросу – оператор
@@
:SELECT '{2,18,3,66}'::integer[] @@ '2&(5|6)';
Пример вывода:Раскрыть type=sql?column? ---------- f (1 row)
-
Проверка по запросу – оператор
~~
:SELECT '3&(18|6)' ~~ '{2,18,3,66}'::integer[];
Пример вывода:Раскрыть type=sql?column? ---------- t (1 row)
-
Индексы (в примере сообщение (
message
) может относиться к одной или нескольким «секциям» (sections
)):-
Создать таблицу, индекс с длиной сигнатуры 32 байта и наполнить тестовыми данными:Раскрыть type=sql
CREATE TABLE message ( mid INT PRIMARY KEY, sections INT[], name text ); CREATE INDEX message_rdtree_idx ON message USING GIST (sections gist__intbig_ops (siglen = 32)); INSERT INTO message VALUES (1, array[3,4], 'Hi, World!'), (2, array[1,4], 'Hello! World!'), (3, array[1,2], 'Hi, my World!'), (4, array[2,5], 'O, my World!');
-
Вывести сообщения из секций 1 или 2 — оператор пересечения
&&
:SELECT message.mid FROM message WHERE message.sections && '{1,2}';
Пример вывода:Раскрыть type=sqlmid ----- 2 3 4 (3 rows)
-
Вывести сообщения из секций 1 и 2 — оператор включения
@>
:SELECT message.mid FROM message WHERE message.sections @> '{1,2}';
Пример вывода:Раскрыть type=sqlmid ----- 3 (1 row)
-
Применить оператор запроса –
query_int = 1 И 2
:SELECT message.mid FROM message WHERE message.sections @@ '1&2'::query_int;
Пример вывода:Раскрыть type=sqlmid ----- 3 (1 row)
-
Применить оператор запроса –
query_int = 1 ИЛИ 2
:SELECT message.mid FROM message WHERE message.sections @@ '1|2'::query_int;
Пример вывода:Раскрыть type=sqlmid ----- 2 3 4 (3 rows)
Дополнительную информацию по поставляемому модулю intarray можно получить по ссылке.