没有以time
为基础的timerange
range data type(当天,没有日期).最近的数字是tsrange
,其中包括日期.最好始终使用timezone-aware变体:demo
select tstzrange('today'::date +'22:00'::time,
'tomorrow'::date+'03:00'::time);
tstzrange |
["2024-02-20 22:00:00+00","2024-02-21 03:00:00+00") |
根据你打算用它做什么,你也可以 Select 你自己的create type
,把它设置成你想要的range based on 103.这将自动创建它的多范围版本,并允许您访问所有built-in functions and operators, like @>
:demo
create type ttzrange as range(subtype=timetz);
--above automatically creates `ttzmultirange` variant
create table test (tmr ttzmultirange);
insert into test
select ttzmultirange(ttzrange('22:00','24:00'),ttzrange('00:00','05:00')) as ttzmr;
select ttzmr @> '01:00'::timetz as "is 1 o'clock in range" from test;
你需要多范围才能让它们跨越"多天"--这并不是完全有效的解释,因为time
应该不会意识到date
.除了拥有内置可支配的巨大好处外,这还使您能够在您的范围内适应中午休息-跨越午夜的范围实际上是两个范围,一个是凌晨,一个是深夜到午夜,中间有很长的休息时间.
您也可以将值拆分到单独的字段中,或创建具有开始/结束time
字段的普通非范围类型:
create type timerange as(start_time time, end_time time);
select ('22:00','03:00')::timerange;
出于某些目的,仅保持开始time
和持续时间interval
可能更容易:
create type timerange2 as(start_time time, duration interval);
这对遏制/重叠判断没有太大帮助(2点钟应该在第一个范围内,但假设日期没有差异,仍然是TOD和TOD,因为它不知道日期):
select (tr2),
(tr2).start_time,
(tr2).duration,
(tr2).start_time+(tr2).duration as end_time,
'02:00' between (tr2).start_time
and (tr2).start_time+(tr2).duration as "2 o'clock in range"
from test2;
tr2 |
start_time |
duration |
end_time |
2 o'clock in range |
(22:00:00,05:00:00) |
22:00:00 |
05:00:00 |
03:00:00 |
F |
(04:00:00,01:30:00) |
04:00:00 |
01:30:00 |
05:30:00 |
F |
非范围方法迫使您"手动"模拟或重新实现内置的函数和运算符和/或处理范围界限.