Диапазонные/мультидиапазонные функции и операторы

Описание диапазонных типов данных см. в разделе Диапазонные типы.

В Таблице 53 приведены специальные операторы, имеющиеся для диапазонных типов. В Таблице 54 приведены специальные операторы, имеющиеся для мультидиапазонных типов. Помимо них для диапазонных и мультидиапазонных типов имеются обычные операторы сравнения, перечисленные в таблице Операторы сравнения. Операторы сравнения сначала сравнивают нижние границы диапазонов, и только если они равны, сравнивают верхние границы. Мультидиапазонные операторы сравнивают каждый диапазон, пока не найдут неравный. Такие операции обычно не приводят к полезному в целом упорядочиванию, но зато позволяют строить по диапазонам уникальные индексы.

Таблица 53. Диапазонные операторы

Оператор
Описание
Пример(ы)
anyrange @> anyrange → boolean
Первый диапазон содержит второй?
int4range(2,4) @> int4range(2,3) → t
anyrange @> anyelement → boolean
Диапазон содержит этот элемент?
'[2011-01-01,2011-03-01)'::tsrange @> '2011-01-10'::timestamp → t
anyrange <@ anyrange → boolean
Первый диапазон содержится во втором?
int4range(2,4) <@ int4range(1,7) → t
anyelement <@ anyrange → boolean
Элемент содержится в этом диапазоне?
42 <@ int4range(1,7) → f
anyrange && anyrange → boolean
Диапазоны пересекаются, то есть имеют какие-либо общие элементы?
3 || ARRAY[4,5,6] → {3,4,5,6}
anyrange << anyrange → boolean
Первый диапазон находится строго слева от второго?
int8range(1,10) << int8range(100,110) → t
anyrange >> anyrange → boolean
Первый диапазон находится строго справа от второго?
int8range(50,60) >> int8range(20,30) → t
anyrange &< anyrange → boolean
Первый диапазон не простирается правее второго?
int8range(1,20) &< int8range(18,20) → t
anyrange &> anyrange → boolean
Первый диапазон не простирается левее второго?
int8range(7,20) &> int8range(5,10) → t
anyrange -|- anyrange → boolean
Диапазоны граничат друг с другом?
numrange(1.1,2.2) -|- numrange(2.2,3.3) → t
anyrange + anyrange → anyrange
Вычисляет объединение диапазонов. Диапазоны должны пересекаться или граничить друг с другом, чтобы их объединение было одним диапазоном (но см. range_merge()).
numrange(5,15) + numrange(10,20) → [5,20)
anyrange * anyrange → anyrange
Вычисляет пересечение диапазонов.
int8range(5,15) * int8range(10,20) → [10,15)
anyrange - anyrange → anyrange
Вычисляет разность диапазонов. Второй диапазон не должен содержаться в первом таким образом, чтобы разностью был не один диапазон.
int8range(5,15) - int8range(10,20) → [5,10)

Таблица 54. Мультидиапазонные операторы

Оператор
Описание
Пример(ы)
anymultirange @> anymultirange → boolean
Первый мультидиапазон содержит второй?
'{[2,4)}'::int4multirange @> '{[2,3)}'::int4multirange → t
anymultirange @> anyrange → boolean
Мультидиапазон содержит этот диапазон?
'{[2,4)}'::int4multirange @> int4range(2,3) → t
anymultirange @> anyelement → boolean
Мультидиапазон содержит этот элемент?
'{[2011-01-01,2011-03-01)}'::tsmultirange @> '2011-01-10'::timestamp → t
anyrange @> anymultirange → boolean
Диапазон содержит этот мультидиапазон?
'[2,4)'::int4range @> '{[2,3)}'::int4multirange → t
anymultirange <@ anymultirange → boolean
Первый мультидиапазон содержится во втором?
'{[2,4)}'::int4multirange <@ '{[1,7)}'::int4multirange → t
anymultirange <@ anyrange → boolean
Мультидиапазон содержится в этом диапазоне?
'{[2,4)}'::int4multirange <@ int4range(1,7) → t
anyrange <@ anymultirange → boolean
Диапазон содержится в этом мультидиапазоне?
int4range(2,4) <@ '{[1,7)}'::int4multirange → t
anyelement <@ anymultirange → boolean
Элемент содержится в этом мультидиапазоне?
42 <@ '{[1,7)}'::int4multirange → t
anymultirange && anymultirange → boolean
Мультидиапазоны пересекаются, то есть имеют какие-либо общие элементы?
'{[3,7)}'::int8multirange && '{[4,12)}'::int8multirange → t
anymultirange && anyrange → boolean
Мультидиапазон пересекает этот диапазон?
'{[3,7)}'::int8multirange && int8range(4,12) → t
anyrange && anymultirange → boolean
Диапазон пересекает этот мультидиапазон?
int8range(3,7) && '{[4,12)}'::int8multirange → t
anymultirange << anymultirange → boolean
Первый мультидиапазон находится строго слева от второго?
'{[1,10)}'::int8multirange << '{[100,110)}'::int8multirange → t
anymultirange << anyrange → boolean
Мультидиапазон находится строго слева от этого диапазона?
'{[1,10)}'::int8multirange << int8range(100,110) → t
anyrange << anymultirange → boolean
Диапазон находится строго слева от этого мультидиапазона?
int8range(1,10) << '{[100,110)}'::int8multirange → t
anymultirange >> anymultirange → boolean
Первый мультидиапазон находится строго справа от второго?
'{[50,60)}'::int8multirange >> '{[20,30)}'::int8multirange → t
anymultirange >> anyrange → boolean
Мультидиапазон находится строго справа от этого диапазона?
'{[50,60)}'::int8multirange >> int8range(20,30) → t
anyrange >> anymultirange → boolean
Диапазон находится строго справа от этого мультидиапазона?
int8range(50,60) >> '{[20,30)}'::int8multirange → t
anymultirange &< anymultirange → boolean
Первый мультидиапазон не простирается правее второго?
'{[1,20)}'::int8multirange &< '{[18,20)}'::int8multirange → t
anymultirange &< anyrange → boolean
Мультидиапазон не простирается правее этого диапазона?
'{[1,20)}'::int8multirange &< int8range(18,20) → t
anyrange &< anymultirange → boolean
Диапазон не простирается правее этого мультидиапазона?
int8range(1,20) &< '{[18,20)}'::int8multirange → t
anymultirange &> anymultirange → boolean
Первый мультидиапазон не простирается левее второго?
'{[7,20)}'::int8multirange &> '{[5,10)}'::int8multirange → t
anymultirange &> anyrange → boolean
Мультидиапазон не простирается левее этого диапазона?
'{[7,20)}'::int8multirange &> int8range(5,10) → t
anyrange &> anymultirange → boolean
Диапазон не простирается левее этого мультидиапазона?
int8range(7,20) &> '{[5,10)}'::int8multirange → t
anymultirange -|- anymultirange → boolean
Мультидиапазоны граничат друг с другом?
'{[1.1,2.2)}'::nummultirange -|- '{[2.2,3.3)}'::nummultirange → t
anymultirange -|- anyrange → boolean
Мультидиапазон граничит с этим диапазоном?
'{[1.1,2.2)}'::nummultirange -|- numrange(2.2,3.3) → t/code>
anyrange -|- anymultirange → boolean
Диапазон граничит с этим мультидиапазоном?
numrange(1.1,2.2) -|- '{[2.2,3.3)}'::nummultirange → t
anymultirange + anymultirange → anymultirange
Вычисляет объединение мультидиапазонов. Мультидиапазонам необязательно пересекаться или граничить друг с другом.
'{[5,10)}'::nummultirange + '{[15,20)}'::nummultirange → {[5,10), [15,20)}
anymultirange * anymultirange → anymultirange
Вычисляет пересечение мультидиапазонов.
'{[5,15)}'::int8multirange * '{[10,20)}'::int8multirange → {[10,15)}
anymultirange - anymultirange → anymultirange
Вычисляет разность мультидиапазонов.
'{[5,20)}'::int8multirange - '{[10,15)}'::int8multirange → {[5,10), [15,20)}

Операторы слева/справа/граничит всегда возвращают false, когда один из диапазонов или мультидиапазонов пуст; то есть считается, что пустой диапазон находится не перед и не после какого-либо другого диапазона.

В остальных случаях пустые диапазоны и мультидиапазоны воспринимаются как нулевой элемент: все, что объединяется с пустым значением, остается неизменным. Все, из чего вычитается пустое значение, остается неизменным. Пустой мультидиапазон имеет точно такие же особенности, что и пустой диапазон. Каждый диапазон содержит пустой диапазон. Каждый мультидиапазон содержит сколько угодно пустых диапазонов.

Операторы объединения и разности выдадут ошибку, если результирующему диапазону нужно содержать два непересекающихся поддиапазона, поскольку у таких диапазонов не может быть представления. Существуют отдельные операторы для объединения и разности, которые принимают мультидиапазонные параметры и возвращают мультидиапазон, и они не выдают ошибку, даже если их аргументы не пересекаются. Поэтому если вам требуется объединение или разность диапазонов, которые могут быть непересекающимися, ошибки можно избежать, если сначала привести диапазоны к мультидиапазонам.

В Таблице 55 приведены имеющиеся функции для диапазонных типов. В Таблице 56 приведены функции для мультидиапазонных типов.

Таблица 55. Диапазонные функции

Функция
Описание
Пример(ы)
lower ( anyrange ) → anyelement
Извлекает нижнюю границу диапазона (NULL, если диапазон пуст или его нижняя граница бесконечна).
lower(numrange(1.1,2.2)) → 1.1
upper ( anyrange ) → anyelement
Извлекает верхнюю границу диапазона (NULL, если диапазон пуст или его верхняя граница бесконечна).
upper(numrange(1.1,2.2)) → 2.2
isempty ( anyrange ) → boolean
Диапазон пустой?
isempty(numrange(1.1,2.2)) → f
lower_inc ( anyrange ) → boolean
Нижняя граница диапазона включена в него?
lower_inc(numrange(1.1,2.2)) → t
upper_inc ( anyrange ) → boolean
Верхняя граница диапазона включена в него?
upper_inc(numrange(1.1,2.2)) → f
lower_inf ( anyrange ) → boolean
Нижняя граница диапазона бесконечна?
lower_inf('(,)'::daterange) → t
upper_inf ( anyrange ) → boolean
Верхняя граница диапазона бесконечна?
upper_inf('(,)'::daterange) → t
range_merge ( anyrange, anyrange ) → anyrange
Вычисляет наименьший диапазон, включающий оба заданных диапазона.
range_merge('[1,2)'::int4range, '[3,4)'::int4range) → [1,4)

Таблица 56. Мультидиапазонные функции

Функция
Описание
Пример(ы)
lower ( anymultirange ) → anyelement
Извлекает нижнюю границу мультидиапазона (NULL, если мультидиапазон пуст или его нижняя граница бесконечна).
lower('{[1.1,2.2)}'::nummultirange) → 1.1
upper ( anymultirange ) → anyelement
Извлекает верхнюю границу мультидиапазона (NULL, если мультидиапазон пуст или его верхняя граница бесконечна).
upper('{[1.1,2.2)}'::nummultirange) → 2.2
isempty ( anymultirange ) → boolean
Мультидиапазон пустой?
isempty('{[1.1,2.2)}'::nummultirange) → f
lower_inc ( anymultirange ) → boolean
Нижняя граница мультидиапазона включена в него?
lower_inc('{[1.1,2.2)}'::nummultirange) → t
upper_inc ( anymultirange ) → boolean
Верхняя граница мультидиапазона включена в него?
upper_inc('{[1.1,2.2)}'::nummultirange) → f
lower_inf ( anymultirange ) → boolean
Нижняя граница мультидиапазона бесконечна?
lower_inf('{(,)}'::datemultirange) → t
upper_inf ( anymultirange ) → boolean
Верхняя граница мультидиапазона бесконечна?
upper_inf('{(,)}'::datemultirange) → t
range_merge ( anymultirange ) → anyrange
Вычисляет наименьший диапазон, включающий весь заданный мультидиапазон.
range_merge('{[1,2), [3,4)}'::int4multirange) → [1,4)
multirange ( anyrange ) → anymultirange
Возвращает мультидиапазон, содержащий только заданный диапазон.
multirange('[1,2)'::int4range) → {[1,2)}
unnest ( anymultirange ) → setof anyrange
Разворачивает мультидиапазон в набор диапазонов. Диапазоны прочитываются в порядке хранения (по возрастанию)
unnest('{[1,2), [3,4)}'::int4multirange) →
    [1,2)
    [3,4)

Функции lower_inc, upper_inc, lower_inf и upper_inf возвращают false, если диапазон или мультидиапазон пуст.