我有tstzrange
类型的列(带时区范围的时间戳),我只需更新此值的上限或下限(并保持包含/独占边界)
我设法改变了
(-infinity,infinity)
与
UPDATE table
SET
my_column = tstzrange(
lower(my_column),
now(),
'()'
)
我有
(-infinity, <current timestamp>)
但我不知道如何保持默认范围的边界..这甚至会将[
]
更改为(
)
答案 0 :(得分:4)
我found function我错过了,有可能这样做
UPDATE table
SET
my_column = tstzrange(
lower(my_column),
now(),
concat(
CASE WHEN lower_inc(my_column) THEN '[' ELSE '(' END,
CASE WHEN upper_inc(my_column) THEN ']' ELSE ')' END
)
)
最好为此创建功能。或者还有其他(更简单/更好)的解决方案吗?
答案 1 :(得分:2)
据我所知,使用CASE WHEN ...是获得界限的最佳方法。以下是一些简单的用户定义函数,它们返回所有本机范围类型的范围界限。
警告:这些函数的行为方式令人惊讶,因为范围类型的行为在sometimes surprising ways。
内置范围类型 int4range,int8range和daterange 都使用 规范形式,包括下限和排除上部 界;也就是说,[)。
和
虽然这里指定了'(]',但显示的值将是 转换为规范形式,因为int8range是离散范围类型。 。
(强调补充)
PostgreSQL将封闭范围从1到10规范化,半开放范围从1到11。
select int4range('[1,10]');
[1,11)
对于左半开的范围,它也是一样的。
select int4range('(1,10]');
[2,11)
range_bounds()返回结果的边界,而不是输入。
select range_bounds(int4range('(1,10]'));
[)
功能
create or replace function range_bounds(in range int4range)
returns char(2) as
$$
select case when lower_inc(range) then '[' else '(' end ||
case when upper_inc(range) then ']' else ')' end;
$$
language sql
returns null on null input;
create or replace function range_bounds(in range int8range)
returns char(2) as
$$
select case when lower_inc(range) then '[' else '(' end ||
case when upper_inc(range) then ']' else ')' end;
$$
language sql
returns null on null input;
create or replace function range_bounds(in range numrange)
returns char(2) as
$$
select case when lower_inc(range) then '[' else '(' end ||
case when upper_inc(range) then ']' else ')' end;
$$
language sql
returns null on null input;
create or replace function range_bounds(in range tsrange)
returns char(2) as
$$
select case when lower_inc(range) then '[' else '(' end ||
case when upper_inc(range) then ']' else ')' end;
$$
language sql
returns null on null input;
create or replace function range_bounds(in range tstzrange)
returns char(2) as
$$
select case when lower_inc(range) then '[' else '(' end ||
case when upper_inc(range) then ']' else ')' end;
$$
language sql
returns null on null input;
create or replace function range_bounds(in range daterange)
returns char(2) as
$$
select case when lower_inc(range) then '[' else '(' end ||
case when upper_inc(range) then ']' else ')' end;
$$
language sql
returns null on null input;
答案 2 :(得分:1)
改进 Mikes great answer。
当我们使用伪类型anyrange时,我们只需要一个函数:
CREATE OR REPLACE FUNCTION range_bounds(IN range anyrange)
RETURNS CHAR(2) AS
$$
SELECT CASE WHEN lower_inc(range) THEN '[' ELSE '(' END ||
CASE WHEN upper_inc(range) THEN ']' ELSE ')' END;
$$
LANGUAGE SQL
RETURNS NULL ON NULL INPUT;