PostgreSQL Range Data Type
This article introduces what is PostgreSQL range data type and how to use PostgreSQL range data type.
Introduction to PostgreSQL Range Types
In PostgreSQL, Range is a data type that represents an interval of values of some element type. For example, a range of integers can represent a range of ages of a group of people, and a range of times can represent a time period for which a conference room is reserved.
The range value is an interval value, respresent by [
, ]
, (
, 和 )
:
- The
[
indicates the start of the range, including the starting value. - The
]
indicates the end of the range, including the end value. - The
(
indicates the start of the range, excluding the starting value. - The
)
indicates the end of the range, excluding the end value.
Here are some examples of ranges:
[a,b]
- Including values betweena
andb
, includinga
andb
.(a,b)
- Including values betweena
andb
, excludinga
andb
.[a,b)
- Including values betweena
andb
, includinga
, excludingb
.(a,b]
- Including values betweena
andb
, excludinga
, includingb
.[a,)
- Includinga
and values greater thana
.(a,)
- Including values greater thana
.(,b]
- Includingb
and values less thanb
.(,b)
- Including values less thanb
.
PostgreSQL 14 introduced the Multirange type, which is a collection of Range types. The representation method is: { range_1, range_2, ...}
.
Each Range type has its corresponding Multirange type.
PostgreSQL built-in Range Types
The following table shows the range types built into PostgreSQL:
Range | Subtype | Multirange |
---|---|---|
int4range |
integer |
int4multirange |
int8range |
bigint |
int8multirange |
numrange |
numeric |
nummultirange |
tsrange |
timestamp without time zone |
tsmultirange |
tstzrange |
timestamp with time zone |
tstzmultirange |
daterange |
date |
datemultirange |
PostgreSQL Range Operators and Functions
The following table shows some PostgreSQL operators for range types:
Operator | Description |
---|---|
@> |
Check if the first operand (range) contains the second operand (range or element) |
<@ |
Check if the second operand (range) contains the first operand (range or element) |
&& |
Check if two ranges have overlapping parts |
<< |
Check if the first range is on the left of the second range |
>> |
Check if the first range is on the right of the second range |
&< |
Check if the first range extends to the right of the second range |
&> |
Check if the first range extends to the left of the second range |
-| - |
Check if two ranges are adjacent |
+ |
Computes the union of two ranges |
* |
Calculate the intersection of two ranges |
- |
Calculate the difference of two ranges |
These operands are also suitable for Multirange type values.
At the same time, PostgreSQL provides many useful functions for Range and Multirange data types, as follows:
- The
isempty()
function checks whether a given range of values is empty. - The
lower_inc()
function checks whether the lower bound of a given range is inclusive. - The
lower_inf()
function checks whether the lower bound of a given range is infinite. - The
lower()
function returns the lower limit of a given range or range of multiple values. - The
multirange()
function returns a multivalued range containing the given range. - The
range_merge()
function computes the smallest range that includes all ranges or the entire multivalued range. - The
unnest()
function expands a multivalued range value into a collection of range values. - The
upper_inc()
function checks whether the upper limit of a given range is inclusive. - The
upper_inf()
function checks whether the upper limit of a given range is infinite. - The
upper()
function returns the upper bound of a given range or a range of multiple values.
PostgreSQL Range Examples
Below are some examples of PostgreSQL Range and Multirange.
To check if a range contains another range, use the following statement:
SELECT '[1,9]'::int4range @> '[3,9]'::int4range;
?column?
----------
t
To check if a range contains a value, use the following statement:
SELECT '[1,9]'::int4range @> 3;
?column?
----------
t
To check if a Multirange contains a range , use the following statement:
SELECT '{[1,5], [7, 9]}'::int4multirange @> '[3,4]'::int4range;
?column?
----------
t
Create Your Own Range
In addition to using PostgreSQL’s built-in range types, you can create your own range types using the CREATE TYPE
statement.
Here is the syntax for creating a custom range type:
CREATE TYPE name AS RANGE (
SUBTYPE = subtype
[, SUBTYPE_OPCLASS = subtype_operator_class ]
[, COLLATION = collation ]
[, CANONICAL = canonical_function ]
[, SUBTYPE_DIFF = subtype_diff_function ]
[, MULTIRANGE_TYPE_NAME = multirange_type_name ]
)
Assuming that you want to create a range type of time (time
) named my_time_range
, use the following statement:
CREATE TYPE my_time_range AS RANGE (
SUBTYPE = time
);
The following statement uses the range type my_time_range
just created:
SELECT my_time_range('10:00:00','12:00:00') @> '11:00:00'::time;
?column?
----------
t
Conclusion
In PostgreSQL, Range is a data type that represents an interval of values of some type. The Multirange type is a collection of Range types.