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]);Пример вывода:icount -------- 5 (1 row) -
sort:Пример в порядке убывания:SELECT sort('{1,223,303,5,33}'::integer[], 'desc');Пример вывода:sort ------------------ {303,223,33,5,1} (1 row)Пример в порядке возрастания без параметраdir:SELECT sort(array[1,223,303,5,33]);Пример вывода:sort ------------------ {1,5,33,223,303} (1 row) -
sort_asc:SELECT sort_asc (array[1,223,303,5,33]);Пример вывода:sort_asc ------------------ {1,5,33,223,303} (1 row) -
sort_desc:SELECT sort_desc (array[1,223,303,5,33]);Пример вывода:sort_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[]);Пример вывода:uniq ------------------------- {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[]));Пример вывода:uniq ----------------------- {1,2,3,5,223,303,332} (1 row) -
idx:Элемент со значениемitemприсутствует в массиве:SELECT idx(array[1,223,303,5,33], 5);Пример вывода:idx ----- 4 (1 row)Элемента со значениемitemнет в массиве:SELECT idx(array[1,223,303,5,33], 6);Пример вывода:idx ----- 0 (1 row) -
subarray:Извлечение части массива, начиная с позиции3длиной в4элемента:SELECT subarray('{1,2,3,4,5,4,3}'::integer[], 3, 4);Пример вывода:subarray ----------- {3,4,5,4} (1 row)Применение функции без указания параметра длины извлекаемой части массиваlen:SELECT subarray('{1,2,3,4,5,4,3}'::integer[], 3);Пример вывода:subarray ----------- {3,4,5,4,3} (1 row) -
intset:SELECT intset(233);Пример вывода:intset -------- {233} (1 row)
-
пересечение:
-
Есть пересечение:
SELECT '{1,2,3,4,5,4,3}'::integer[] && '{1,4,6}'::integer[];Пример вывода:?column? ---------- t (1 row) -
Нет пересечения:
SELECT '{1,2,3,4,5,4,3}'::integer[] && '{12,33}'::integer[];Пример вывода:?column? ---------- f (1 row)
-
-
содержание одного массива в другом:
-
правый массив содержится в левом:
SELECT '{1,2,3,4,5,4,3}'::integer[] @> '{4,5,4}'::integer[];Пример вывода:?column? ---------- t (1 row) -
левый массив содержится в правом:
SELECT '{2,3,8}'::integer[] <@ '{1,2,3,4,5,4,3}'::integer[];Пример вывода:?column? ---------- f (1 row)
-
-
добавление элемента в конец массива:
SELECT '{14,54}'::integer[] + 34;Пример вывода:?column? ------------ {14,54,34} (1 row) -
соединение двух массивов:
SELECT '{14,54}'::integer[] + '{2,3,8}'::integer[];Пример вывода:?column? --------------- {14,54,2,3,8} (1 row) -
удаление элемента из массива:
SELECT '{14,54,34}'::integer[] - 54;Пример вывода:?column? ---------- {14,34} (1 row) -
удаление элементов правого массива из левого:
SELECT '{2,2,18,3,3,66,3}'::integer[] - '{2,3,8}'::integer[];Пример вывода:?column? ---------- {18,66} (1 row) -
объединение аргументов:
-
объединение с элементом:
SELECT array[2,4,8,66] | 55;Пример вывода:?column? --------------- {2,4,8,55,66} (1 row) -
объединение с массивом:
SELECT array[2,4,8,66] | array[1,3,55];Пример вывода:?column? ------------------- {1,2,3,4,8,55,66} (1 row)
-
-
пересечение аргументов:
SELECT '{2,18,3,66}'::integer[] & '{2,3,8}'::integer[];Пример вывода:?column? ---------- {2,3} (1 row) -
соответствие запросу:
-
проверка по запросу – оператор
@@:SELECT '{2,18,3,66}'::integer[] @@ '2&(5|6)';Пример вывода:?column? ---------- f (1 row) -
Проверка по запросу – оператор
~~:SELECT '3&(18|6)' ~~ '{2,18,3,66}'::integer[];Пример вывода:?column? ---------- t (1 row)
-
Индексы (в примере сообщение (
message) может относиться к одной или нескольким «секциям» (sections)):-
Создать таблицу, индекс с длиной сигнатуры 32 байта и наполнить тестовыми данными:
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}';Пример вывода:mid ----- 2 3 4 (3 rows) -
Вывести сообщения из секций 1 и 2 — оператор включения
@>:SELECT message.mid FROM message WHERE message.sections @> '{1,2}';Пример вывода:mid ----- 3 (1 row) -
Применить оператор запроса –
query_int = 1 И 2:SELECT message.mid FROM message WHERE message.sections @@ '1&2'::query_int;Пример вывода:mid ----- 3 (1 row) -
Применить оператор запроса –
query_int = 1 ИЛИ 2:SELECT message.mid FROM message WHERE message.sections @@ '1|2'::query_int;Пример вывода:mid ----- 2 3 4 (3 rows)
Дополнительную информацию по поставляемому модулю intarray можно получить по ссылке.