Tsrange - Расчет разницы между двумя диапазонами

У меня есть две таблицы free_time и appointment. Оба содержат tsranges.

Как написать запрос (или функцию), определяющий фактическое свободное время после «вычитания» разницы appointment из freetime?

INSERT INTO free_time(freetime)
VALUES('[2017-04-19 09:00, 2017-04-19 12:30)');

INSERT INTO appointment(appointment)
VALUES('[2017-04-19 10:30, 2017-04-19 11:30)');

Я хочу, чтобы результат был примерно таким:

["2017-04-19 9:00","2017-04-19 10:30:00"), 
["2017-04-19 11:30:00","2017-04-19 12:30:00")

person Jonathan Eustace    schedule 19.04.2017    source источник
comment
Гарантировано ли, что встречи являются подмножеством свободного времени?   -  person Evan Carroll    schedule 19.04.2017
comment
Да, это было бы правильно.   -  person Jonathan Eustace    schedule 19.04.2017


Ответы (1)


Вам придется разбить диапазон на части из документов

Операторы объединения и разности потерпят неудачу, если результирующий диапазон должен содержать два непересекающихся поддиапазона, поскольку такой диапазон не может быть представлен.

Для этого вы можете использовать lower и upper.

SELECT tsrange(  lower(freetime), lower(appointment)  )  AS before_appointment,
       tsrange(  upper(appointment), upper(freetime)  )  AS after_appointment
FROM ( VALUES
  (
    '[2017-04-19 09:00, 2017-04-19 12:30)'::tsrange,
    '[2017-04-19 10:30, 2017-04-19 11:30)'::tsrange
  )
) AS t(freetime,appointment)
WHERE freetime @> appointment;

              before_appointment               |               after_appointment               
-----------------------------------------------+-----------------------------------------------
 ["2017-04-19 09:00:00","2017-04-19 10:30:00") | ["2017-04-19 11:30:00","2017-04-19 12:30:00")
(1 row)
person Evan Carroll    schedule 19.04.2017
comment
@JonathanEustace имейте в виду, что это работает, только если встреча соответствует диапазону свободного времени. - person Evan Carroll; 19.04.2017
comment
У меня есть еще один более сложный вопрос, возможно, я должен был задать его первым. Что, если бы у меня была таблица строк диапазонов свободного времени и таблица строк диапазонов встреч? Я хочу, чтобы все свободное время было доступно после вычитания встреч. Как бы я построил это? Если хочешь, я могу задать другой вопрос. - person Jonathan Eustace; 19.04.2017
comment
Да, сделайте из этого еще один вопрос с примерными данными. - person Evan Carroll; 19.04.2017
comment
Сделать это сейчас, вероятно, займет около 15 минут. Большое спасибо! - person Jonathan Eustace; 19.04.2017
comment
Я добавил вопрос. - person Jonathan Eustace; 19.04.2017