https://www.postgresql.org/docs/current/rangetypes.html
8.17 Range 类型
Range 类型,可以描述一个数据区间,有明确的子类型,而且子类型应该能被排序。
8.17.1 内置类型
PostgresSQL 有如下 range 类型:
- int4range — Range of integer, int4multirange — corresponding Multirange
- int8range — Range of bigint, int8multirange — corresponding Multirange
- numrange — Range of numeric, nummultirange — corresponding Multirange
- tsrange — Range of timestamp without time zone, tsmultirange — corresponding Multirange
- tstzrange — Range of timestamp with time zone, tstzmultirange — corresponding Multirange
- daterange — Range of date, datemultirange — corresponding Multirange
8.17.2 示例
CREATE TABLE reservation (room int, during tsrange);
INSERT INTO reservation VALUES (1108, '[2010-01-01 14:30, 2010-01-01 15:30)');
-- Containment
SELECT int4range(10, 20) @> 3; -- FALSE
-- Overlaps
SELECT numrange(11.1, 22.2) && numrange(20.0, 30.0); -- 返回TRUE, 表示两个区间有交集
-- Extract the upper bound
SELECT upper(int8range(15, 25)); -- 返回 25, 表示区间的上界
-- Compute the intersection
SELECT int4range(10, 20) * int4range(15, 25); -- 返回[15, 20), 表示交集区间
-- Is the range empty?
SELECT isempty(numrange(1, 5)); -- 返回 FALSE, 表示区间为空
8.17.3 开闭区间
每个非空区间都有两个界限,即下界和上界。这些值之间的所有点都包含在该范围内。包含边界意味着边界点本身也包括在范围内,而排除边界意味着边界点不包括在范围内。
- [是左闭区间,]是右闭区间
- (是左开区间,)是右开区间
函数 lower_inc 和 upper_inc 分别测试范围值的下界和上界,是否为闭区间。若为闭区间则返回 TRUE。
select lower_inc(numrange(10, 20)); -- 返回 TRUE 表示左闭区间
select upper_inc(numrange(10, 20)); -- 返回 FALSE 表示右开区间
select lower_inc(tsrange('[2010-01-01 14:30, 2010-01-01 15:30]')); -- 返回 TRUE 表示左闭区间
select upper_inc(tsrange('[2010-01-01 14:30, 2010-01-01 15:30]')); -- 返回 TRUE 表示右闭区间
select lower_inc(tsrange('[2010-01-01 14:30, 2010-01-01 15:30)')); -- 返回 TRUE 表示左闭区间
select upper_inc(tsrange('[2010-01-01 14:30, 2010-01-01 15:30)')); -- 返回 FLASE 表示右开区间
8.17.4 无穷区间
- 可以没有区间左端点,比如
(,3]
则表示 <=3 的都在区间内。 - 可以没有区间右端点,比如
(,3]
则表示 <=3 的都在区间内。 - 可以没有区间左和右端点,这种闭区间会被 pg 默认转换为 开区间,例如
[,]
会被转换为(,)
- 也可以手动指定 infinity 为端点,例如:
- [today,infinity) excludes the special timestamp value infinity,这种区间上手动指定不包含 infinity 的。
- while [today,infinity] include it, as does [today,) and [today,]. 这些都是区间包含 infinity 的。
最重要的,还是可以用 函数 lower_inc 和 upper_inc 测试。