在计算指标和查询数据的过程中,有出现判断两个区间是否有交集的情况。类似时间段,指标区间。这些在去判断是否存在交集的时候,使用Range类型判断非常方便。之前没有用过,使用两个值进行大小判断非常麻烦。
搜了一下发现还是可以直接使用区间判断交集的。
这里我是分别两个数字字段,将他们转换成了两个Range,然后再去判断交集,默认左闭右开,例如下面可以指定‘[]’。
numrange(qnetar, agree_standard_value) && numrange(starting_value, end_value)
numrange('202412'::numeric,'202503'::numeric, '[]') && numrange(start_val::numeric ,end_val::numeric, '[]')
内置Range类型
pg数据库中内置了一些常用的Range类型。
- int4range : 4字节整数的范围类型
- int8range : 8字节大整数的范围类型
- numrange : numeric的范围类型
- tsrange : 无时区的时间戳范围类型
- tstzrange : 带时区的时间戳范围类型
- daterange : 日期的范围类型
自定义Range类型
自定义Range类型的语法如下:
CREATE TYPE name AS RANGE (
subtype=subtype_name
[,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类型;
- SUBTYPE_DIFF = subtype_diff_function:定义子类型的差别函数。
Range区间开闭
range类型的的表示可以用“(”、“)”,也可以用“[”、“]”,小括号表示是开区间,也就是说范围不包括边界;中括号表示闭区间,也就是说范围包含边界。
常用的操作符和函数
逻辑判断操作
| 操作符 | 描述 |
|---|---|
| = | 等于 |
| <> | 不等于 |
| < | 小于 |
| > | 大于 |
| <= | 小于等于 |
| >= | 大于等于 |
| @> | 包含(左边包含了右边) |
| <@ | 被包含(右边包含左边) |
| && | 重叠(两个范围有交集) |
| << | 严格在左(没有重叠值) |
| >> | 严格在右 |
| &< | 没有扩展到右边 |
| &> | 没有扩展到左边 |
计算操作
| 操作符 | 描述 |
|---|---|
| -l- | 链接在一起(值没有交集) |
| + | union(将两个范围合并在一起) |
| * | intersection |
| – | difference |
函数
lower
lower(anyrange) : 获得范围的起始值
upper
upper(anyrange):获得范围的结束值
这里面获取的范围结束值是不包含在范围内的最大值
isempty
isempty(anyrange):是否是空范围
lower_inc
lower_inc(anyrange):起始值是否在范围内
upper_inc
upper_inc(anyrange):结束值是否在范围内
lower_inf
lower_inf(anyrange):起始值是否是一个无穷值
upper_inf
upper_inf(anyrange):结束值是否是一个无穷值
