
Range类型是一种特有的类型,用于表现范围,如一个整数的范围、一个时间的范围,而范围底下的基本类型(如整数、时间)则被成为Range类型的subtype。
Range数据类型可以更快的在范围条件查询中检索到数据。
创建Range类型
PostgreSQL中内置了一些常用的Range类型,这些类型不需要创建就可以直接使用
- int4range: 4字节整数的范围类型。
- int8range: 8字节大整数的范围类型。
- numrange: numeric的范围类型。
- tsrange: 无时区的时间戳的范围类型。
- tstzrange: 带时区的时间戳的范围类型。
- daterange: 日期的范围类型。
使用CREATE TYPE函数创建Range类型
CREATE TYPE name AS RANGE (
SUBTYPE = subtype
[ , SUBTYPE_OPCLASS = subtype_operator_class ]
[ , COLLATION = collation ]
[ , CANONICAL = canonical_function ]
[ , SUBTYPE_DIFF = subtype_diff_function ]
)
# SUBTYPE=subtype:指定子类型。
# SUBTYPE_OPCLASS=subtype_operator_class:指定子类型的操作符。
# COLLATION=collation:指定排序规则。
# CANONICAL=canonical_function:如果要创建一个稀疏的Range类型而不是一个连续的Range类型,那么就需要定义此函数。
# SUBTYPE_DIFF=subtype_diff_function:定义子类型的差别函数。
# 创建Range类型
CREATE TYPE floatrange AS RANGE (
subtype = float8,
subtype_diff = float8mi
);

Range类型的输入与输出
输入格式
- ‘[value1,value2]’
- ‘[value1,value2)’
- ‘(value1,value2]’
- ‘(value1,value2)’
- ‘empty’
“(”“)”表示范围内不包括此元素
“[”“]”表示范围内包括此元素。
如果是稀疏类型的Range,其内部存储的格式为“’[value1,value2)’”。
“‘empty’”表示空,即范围内不包括任何内容。
# int4range类型
select '(0,6)'::int4range;
select '[0,6)'::int4range;
select '[0,6]'::int4range;
select 'empty'::int4range;
# 对于连续类型的Range,内部存储则是精确存储的,如numrange类型
select '[0,6]'::numrange;
select '[0,6)'::numrange;
select '(0,6]'::numrange;
select '(0,6)'::numrange;
# Range类型还可以表示极值的区间
select '[1,)'::int4range;
# “[1,]”就表示从1到int4可以表示的最大数值。
select '[,1)'::int4range;
# “[,1]”指的是从int4类型可以表示的最小值到1的范围。
# 对于numrange,表示的是无穷大或无穷小
# 从1到无穷大
select '[1,)'::numrange;
# 从负无穷到1
select '[,1)'::numrange;
# 使用Range类型的构造函数输入Range类型的值,Range类型的构造函数名称与类型名称相同
select int4range(1,10,'[)');
select int4range(1,10,'()');
select int4range(1,10);


Range类型的操作符、函数
操作符
| 操作符 | 描述 | 例子 | 结果 |
|---|---|---|---|
| = | 等于 | select int4range’[1,5)’ = ‘[1,4]’::int4range; | t |
| <> | 不等于 | select numrange(1.1,1.2) <> numrange(1.1,1.3); | t |
| < | 小于 | select int4range ‘[1,10)’ < int4range’[2,3)’; | t |
| > | 大于 | select int4range ‘[2,3)’ > int4range’[1,100)’; | t |
| <= | 小于等于 | select int4range’[2,3)’<= int4range’[1,2)’; | f |
| >= | 大于等于 | select int4range’[2,3)’>= int4range’[1,2)’; | t |
| @> | 包含(左边包含了右边) | select int4range’[1,3)’ @> int4range’[1,2)’; | t |
| <@ | 被包含(右边包含左边) | select int4range’[1,2)’ <@ int4range’[1,4)’; | t |
| && | 重叠(两个范围有交集) | select int4range’[1,2)’ && int4range’[1,4)’; | t |
| << | 严格在左(没有重叠值) | select int4range’[1,2)’ << int4range’[2,4)’; | t |
| >> | 严格在右 | select int4range’[2,4)’ >> int4range’[1,2)’; | t |
| &< | 没有扩展到右边 | select int4range’[1,2)’ &< int4range’[1,4)’; | t |
| &> | 没有扩展到左边 | select int4range’[1,2)’ &> int4range’[1,4)’; | t |
| -|- | 链接在一起(值没有交集) | select int4range’[1,2)’ -|- int4range’[2,4)’; | t |
| + | union(将两个范围合并在一起) | select int4range’[1,2)’ + int4range’[2,4)’; | [1,4) |
| * | intersection | select int4range’[1,4)’ * int4range’[2,5)’; | [2,4) |
| - | difference | select int4range’[1,4)’ - int4range’[2,5)’; | [1,2) |


函数
# lower(anyrange) : 获得范围的起始值
select lower(int4range '[11,22)');
select lower(int4range '[11,22)') is null;
select lower(int4range '[11,22)') is not null;
# upper(anyrange):获得范围的结束值
select upper(int4range '[11,22)');
select upper(int4range '[11,34]');
# 获取的范围结束值是不包含在范围内的最大值!
# isempty(anyrange):是否是空范围
select isempty(int4range'empty');
select isempty(int4range'(,)');
select isempty(int4range'(1,1)');
select isempty(int4range'[1,2)');
# lower_inc(anyrange):起始值是否在范围内
select lower_inc(int4range'(1,2)');
select lower_inc(int4range'[1,2)');
select lower_inc(int4range'(1,4]');
# upper_inc(anyrange):结束值是否在范围内
select upper_inc(int4range'(1,2)');
select upper_inc(int4range'(1,3]');
# lower_inf(anyrange):起始值是否是一个无穷值
select lower_inf(int4range'[,2)');
# upper_inf(anyrange):结束值是否是一个无穷值
select upper_inf(int4range'[1,)');


「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




