Postgres附带了一个名为Range Types的好功能,它提供了有用的范围功能(重叠,包含等)。
我希望使用daterange
类型,但我认为该类型是通过一个尴尬的选择实现的:日期范围的上限是排除。这意味着,如果我将我的值定义为2014/01/01 - 2014/01/31
,则会显示为[2014/01/01, 2014/01/31)
,并且该范围内的排除的1月31日!
我认为这是错误的默认选择。我不能想到现实生活中的任何应用或参考,假设日期范围的结束日期被排除在外。至少不符合我的经验。
我想为包含下限和上限的日期实现范围类型,但是我正在使用Postgres文档墙:关于如何创建新的离散范围类型的参考资料是含糊不清的,缺少任何示例(取自文档:Creating a canonical function is a bit tricky, since it must be defined before the range type can be declared)。
有人可以提供一些帮助吗?甚至直接实施本身;它应该是5-10行代码,但将这5-10行放在一起是一项严肃的研究工作。
编辑:澄清:我正在寻找有关如何创建正确类型的信息,以便插入[2014/01/01, 2014/01/31]
导致upper(daterange) = '2014/01/31'
。使用现有的日期范围类型,此值将“转换”为[2014/01/01, 2014/02/01)
并提供upper(daterange) = '2014/02/01'
答案 0 :(得分:5)
注意第三个构造函数参数:
select daterange('2014/01/01', '2014/01/31', '[]');
daterange
-------------------------
[2014-01-01,2014-02-01)
或包含上限的直接演员:
select '[2014/01/01, 2014/01/31]'::daterange;
daterange
-------------------------
[2014-01-01,2014-02-01)
不是新类型(错误的方法恕我直言),而是一个正确的功能:
create function inclusive_upper_daterange(dtr daterange)
returns date as $$
select upper(dtr) - 1;
$$ language sql immutable;
select inclusive_upper_daterange('[2014/01/01, 2014/01/31]'::daterange);
inclusive_upper_daterange
---------------------------
2014-01-31
答案 1 :(得分:0)
使用PostgresSQL 11,您可以使用upper_inc函数来解决表示部分,例如:
select
WHEN upper_inc(mydaterange) THEN upper(mydaterange)
ELSE date(upper(mydaterange)- INTERVAL '1 day')
END
答案 2 :(得分:-1)
CREATE or replace FUNCTION to_timestamptz(arg1 timestamptz, arg2 timestamptz) RETURNS float8 AS
'select extract(epoch from (arg2 - arg1));' LANGUAGE sql STRICT
IMMUTABLE;
;
create type tsrangetz AS RANGE
(
subtype = timestamptz,
subtype_diff =
to_timestamptz
)
;
select tsrangetz(current_date, current_date + 1)
--["2020-10-05 00:00:00+07","2020-10-06 00:00:00+07")
;