#postgresql #date-range
#postgresql #диапазон дат
Вопрос:
Я не вижу, как создать диапазон дат с infinity
в качестве включающей верхней границы. Postgres преобразует оба входных параметра в эксклюзивную верхнюю границу:
create table dt_overlap (
id serial primary key,
validity daterange not null
);
insert into dt_overlap (validity) values
('["2019-01-01", infinity]'),
('["2019-02-02", infinity)');
table dt_overlap;
id │ validity
────┼───────────────────────
1 │ [2019-01-01,infinity)
2 │ [2019-02-02,infinity)
select id,
upper(validity),
upper_inf(validity),
not isfinite(upper(validity)) as is_inf
from dt_overlap;
id │ upper │ upper_inf │ is_inf
────┼──────────┼───────────┼────────
1 │ infinity │ f │ t
2 │ infinity │ f │ t
То, что оба значения дают одинаковые результаты, отчасти ожидаемо, поскольку инклюзивная верхняя граница infinity]
была приведена к исключительной верхней границе infinity)
.
Такой же проблемы не существует для нижнего предела диапазона, поскольку диапазон дат сохраняет включающую нижнюю границу и, таким образом, lower_inf()
возвращает true
.
Протестировано и воспроизведено с Postgresql 9.6.5 и Postgresql 10.3.
Есть идеи?
Ответ №1:
Другой способ создания неограниченного диапазона — полностью исключить верхнюю границу, например '["2019-01-01",)'
with dt_overlap (validity) as (
values
('["2019-01-01", infinity]'::daterange),
('["2019-02-01",]'::daterange)
)
select validity,
upper_inf(validity)
from dt_overlap;
приводит к
validity | upper_inf
---------------------- ----------
[2019-01-01,infinity) | false
[2019-02-01,) | true
Комментарии:
1. Это более чем академично. В нынешнем виде
upper_inf()
вернет false для всех возможных значений (включаяinfinity
) в диапазоне дат. Я нахожу это несколько нелогичным.2. @dland: Интересно, зачем вам для начала проверять верхнюю (или нижнюю) границу? Какой вариант использования стоит за этим? Обычно я использую только функции «сдерживания» и не беспокоюсь о фактических значениях для верхней или нижней границы
3. Зарегистрирован как #15675
4. Извините, я опоздал, но это не ошибка. В документации говорится: о
lower
, аupper
функции возвращают null, если диапазон пуст или запрошенная граница бесконечна.5. О, я понимаю. Вы жалуетесь на
upper_inf('["2019-01-01",infinity]'::daterange)
. Да, в этом есть смысл. Я просмотрел код, иinfinity
он обрабатывается как обычное значение. Я думаю, это спорно.