Создание временных интервалов для записи на прием с помощью функции создания рядов

Я пытаюсь создать доступную функцию временного интервала. для каждого дня я фиксирую время начала и время окончания.

for eg: start time is 08:00 AM and end time is 03:00 PM.

У меня есть другая таблица, в которой записано время перерыва в тот же день,

for eg: 11:00 AM to 11:15 AM and 01:00 PM to 1:30 PM.

А в другой таблице я храню уже забронированные слоты

for eg: 
09:00 AM to 09:30 AM
11:15 AM to 11:45 AM
01:30 PM 02:00PM

Я использую generate_series для создания временных интервалов между временем начала и окончания.

select * FROM generate_series(
       timestamp '2016-11-09 08:00 AM',
       timestamp '2016-11-09 03:00 PM',
       INTERVAL '30m'
    ) t

Мне нужно исключить время перерыва и уже забронированное время из этой сгенерированной серии. Я попытался использовать функцию except, но этот слот с 11:15 до 11:45 удалить не удалось. Как мне вообще написать условие для удаления этого?

Кроме запроса

SELECT t
    FROM generate_series(
       timestamp  '2016-11-09 08:00 AM',
       timestamp  '2016-11-09 03:00 PM',
       INTERVAL '1 hour'
    ) t
    EXCEPT
    SELECT concat(start_date,' ' , start_time)::timestamp as booked 
    FROM my_table where start_date::date = '2016-11-09';

детали my_table

CREATE TABLE public.my_table
(
id bigint NOT NULL,
start_date character varying(500),
start_time character varying(500),
CONSTRAINT pk_my_table PRIMARY KEY (id))
WITH (
OIDS=FALSE
);

person Shamseer Pc    schedule 22.10.2018    source источник
comment
Как именно вы храните эти забронированные слоты в виде строк? Как называются таблицы? а колонки? Покажите нам свой запрос, в котором используется функция except.   -  person Paul Maxwell    schedule 22.10.2018
comment
@Used_By_Already Спасибо за быстрый ответ. Да, я сохраняю его как строку. В таблице есть столбцы start_date и start_time. Я обновил свой вопрос, добавив кроме запроса.   -  person Shamseer Pc    schedule 22.10.2018
comment
Извините, но зачем вам использовать разные символы (500) для даты и времени? Информация о дате и / или времени обрабатывается НАМНОГО эффективнее в их правильных типах данных, например. postgresql.org/docs/9.1/static/datatype-datetime.html Знаете ли вы, что данные о дате и времени хранятся в виде наборов чисел? (и поэтому они намного эффективнее струнных)   -  person Paul Maxwell    schedule 23.10.2018
comment
Вы еще не ответили на мой комментарий или ответ   -  person Paul Maxwell    schedule 23.10.2018


Ответы (1)


Следующие работы, я предлагаю вам использовать меньший интервал, вероятно, 15 минут:

with my_table as (
    select '09:00 AM' start_time , '2016-11-09'::character varying start_date
    )

SELECT *
    FROM generate_series(
       timestamp  '2016-11-09 08:00 AM',
       timestamp  '2016-11-09 03:00 PM',
       INTERVAL '15 minutes'
    ) t
EXCEPT
SELECT concat(start_date,' ' , start_time)::timestamp as booked 
FROM my_table where start_date::date = '2016-11-09'

Но, честно говоря, я просто не стал бы хранить встречу в виде строки, которая выглядит как дата, или строки, которая выглядит как время дня. Столбец с символом (500) с радостью принимает данные, такие как 'this is not a date or a time', и внезапно у вас возникает ошибка, потому что он не конвертируется. или даты, такие как 30/02/2019, могут присутствовать в данных, и их трудно найти.

Почему бы просто не сохранить начало встречи как отметку времени? Это было бы намного эффективнее. например

with my_table as (
    select '2016-11-09 09:00:00'::timestamp start_date
    )


SELECT *
    FROM generate_series(
       timestamp  '2016-11-09 08:00 AM',
       timestamp  '2016-11-09 03:00 PM',
       INTERVAL '15 minutes'
    ) t
EXCEPT
SELECT start_date
FROM my_table 
where start_date >= '2016-11-09' and start_date < '2016-11-10'

Такой запрос будет использовать индекс этого столбца start_date для фильтрации данных.

Пожалуйста, не используйте строки для хранения даты или времени. Я бы тоже не стал отделять дату от времени суток.

person Paul Maxwell    schedule 22.10.2018