PostgreSQL中tstzrange与timestamptz的&&运算符不存在问题咨询
为什么PostgreSQL中
tstzrange和单个timestamptz不能用&&判断重叠? 这个问题我之前也踩过坑——虽然逻辑上我们觉得“范围和时间点重叠”是合理的,但PostgreSQL的操作符系统是严格基于类型匹配的,没有预定义tstzrange(带时区的时间范围)和timestamptz(带时区的时间戳)之间的&&(重叠判断)操作符,这就是报错的核心原因。
PG的&&操作符原本是为两个同类型范围设计的,比如tstzrange && tstzrange,用来判断两个范围是否有重叠区域。而单个时间点属于标量类型,不是范围类型,所以没有对应的操作符实现。
解决方法
其实有几种简单的方式实现你想要的逻辑:
1. 把时间点转换成单点范围
既然&&只认范围类型,我们可以把单个时间点包装成一个起始和结束都相同的闭合范围,再进行重叠判断:
SELECT tstzrange( '2019-05-01', '2019-05-09' ) && '[2019-05-01, 2019-05-01]'::tstzrange;
或者用函数生成单点范围:
SELECT tstzrange( '2019-05-01', '2019-05-09' ) && tstzrange('2019-05-01', '2019-05-01', '[]');
这里的'[]'表示闭合范围,确保时间点被包含在内。
2. 使用更贴合需求的@>操作符
逻辑上“时间点与范围重叠”等价于“时间点在范围内”,而PG专门提供了@>操作符来判断元素是否被范围包含,用这个更直接:
SELECT tstzrange( '2019-05-01', '2019-05-09' ) @> '2019-05-01'::timestamptz;
这个写法不仅更简洁,执行效率和重叠判断完全一致,而且语义更清晰。
3. 使用范围重叠的函数形式
如果你一定要用重叠的逻辑表达,也可以调用底层函数range_overlaps,同样需要把时间点转成范围:
SELECT range_overlaps(tstzrange( '2019-05-01', '2019-05-09' ), tstzrange('2019-05-01', '2019-05-01', '[]'));
内容的提问来源于stack exchange,提问作者Eugen Konkov
相关产品推荐
相关产品推荐

