6

使用 PostgreSQL 9.4:

SELECT x, lower(x), upper(x) FROM (SELECT '[1,2]'::numrange x) q;
> [1,2] | 1 | 2      -- looks OK

SELECT x, lower(x), upper(x) FROM (SELECT '[1,2]'::int4range x) q;
> [1,3) | 1 | >>3<<  -- this is unexpected

让我们进一步检查:

SELECT x, lower(x), upper(x) FROM (SELECT '[1,3)'::numrange x) q1;
> [1,3) | 1 | 3      -- looks OK

SELECT x, lower(x), upper(x) FROM (SELECT '[1,3]'::numrange x) q1;
> [1,3] | 1 | 3      -- looks OK

来自 pg 文档:

上(任意范围) | range 的元素类型 | 范围上限 | 上(数字范围(1.1,2.2))| 2.2

虽然3从技术上讲是整数范围的上限[1,3) ∩ ℕ = {1, 2},但所有自然数 ≥ 2 也是如此。我希望该upper函数返回范围的上界(最小上限)。

我错过了什么吗?

4

2 回答 2

2

发生这种情况是因为int4range离散范围。这样的范围总是自动转换为它们的规范表示,以便能够测试等价性,例如:

SELECT '[4,8]'::int4range = '(3,9)'::int4range

内置范围类型int4range,int8rangedaterange都使用规范形式,包括下限和不包括上限;也就是说,[). 但是,用户定义的范围类型可以使用其他约定。

于 2015-01-15T19:10:18.353 回答
1

封闭范围的规范形式[1,2]是半开(或半封闭)范围[1,3)。函数 upper() 返回规范形式的上限。

select upper(int4range(1, 2, '[]'));  -- Canonical form is '[1,3)'
--
3

该范围不包含值 3。

select int4range(1, 2, '[]') @> 3;
--
f

内置范围类型 int4range、int8range 和 daterange 都使用包含下限但不包括上限的规范形式;那是, [)。但是,用户定义的范围类型可以使用其他约定。

来源:PostgreSQL 离散范围类型

如果您需要知道 upper() 返回的值是否包含在内,可以调用不同的函数。

select upper_inc(int4range(1, 2, '[]'));
--
f
于 2015-01-15T19:37:14.473 回答