2016-04-06 4 views
2

У меня есть таблица с резервированием в ней.Расчет свободного времени Слоты из таблицы бронирования

('2016-04-06 09:00:00', '2016-04-06 09:15:00'), 
('2016-04-06 11:00:00', '2016-04-06 11:30:00'), 
('2016-04-06 12:00:00', '2016-04-06 12:45:00'), 
('2016-04-06 16:30:00', '2016-04-06 16:45:00'), 

Бронирование может быть произведено только с 07:00 до 19:00. Что я хочу сделать, это получить/рассчитать свободное время Слот между, до и после оговорок, всегда для текущей даты.

Возможно ли это сделать на DB-Layer, возможно, с сохраненными процедурами? Может ли кто-нибудь помочь мне с этим?

+0

anycode вы устали? show –

ответ

2

Использование ниже данных образца:

select * into #t from (
select 1 ID, '2016-04-06 09:00:00' r_start , '2016-04-06 09:15:00' r_end union 
select 2, '2016-04-06 11:00:00', '2016-04-06 11:30:00'union 
select 3, '2016-04-06 12:00:00', '2016-04-06 12:45:00'union 
select 4, '2016-04-06 16:30:00', '2016-04-06 16:45:00') AS bookdata 

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

;with booked as (
    select r_start, r_end 
    , LAG(r_end) over (order by r_end) PrevBook 
    , LEAD(r_start) over (order by r_start) NextBook 
    from #t 
) 
select IsNull(PrevBook, '2016-04-06 07:00:00') AS FreeStart, r_start AS FreeEnd 
from booked 
union 
select r_end, IsNull(NextBook, '2016-04-06 19:00:00') 
from booked 

Результат

+---------------------+---------------------+ 
|  FreeStart  |  FreeEnd  | 
+---------------------+---------------------+ 
| 2016-04-06 07:00:00 | 2016-04-06 09:00:00 | 
| 2016-04-06 09:15:00 | 2016-04-06 11:00:00 | 
| 2016-04-06 11:30:00 | 2016-04-06 12:00:00 | 
| 2016-04-06 12:45:00 | 2016-04-06 16:30:00 | 
| 2016-04-06 16:45:00 | 2016-04-06 19:00:00 | 
+---------------------+---------------------+ 

Если вы используете SQL старше 2012 не будет иметь опережение и запаздывание, так что вы можете использовать ниже запрос вместо этого, предполагается, что ваш иметь идентификатор в качестве первичного ключа

;with booked as (
    select r_start, r_end 
    , (select top 1 r_end from #t where ID < tbl.ID order by ID desc) PrevBook 
    , (select top 1 r_start from #t where ID > tbl.ID order by ID) NextBook 
    from #t tbl 
) 
select IsNull(PrevBook, '2016-04-06 07:00:00') AS FreeStart, r_start AS FreeEnd 
from booked 
union 
select r_end, IsNull(NextBook, '2016-04-06 19:00:00') 
from booked 

** Пожалуйста, «Отметить как ответ», если этот пост ответил на вопрос

+0

Привет, Flicker, iam, используя SQL Server 2008. LAG и LEAD не работают в 2008 году. Как я могу переписать две строки? – Bashud

+0

Hummm, это делает его немного сложным. у вас есть цельный первичный ключ в вашей таблице? – FLICKER

+0

Да, у меня есть первичный ключ Integer в моей таблице – Bashud

1

это работает для данных, при условии

select * into #t from (

select '2016-04-06 09:00:00'r_start , '2016-04-06 09:15:00'r_end union all 
select'2016-04-06 11:00:00', '2016-04-06 11:30:00'union all 
select'2016-04-06 12:00:00', '2016-04-06 12:45:00'union all 
select'2016-04-06 16:30:00', '2016-04-06 16:45:00') x 

--returns duration between 1st reservation and the next 
select 
datediff(MINUTE,x.r_end,y.r_start)/60 'hours' 
,datediff(MINUTE,x.r_end,y.r_start) - datediff(MINUTE,x.r_end,y.r_start)/60 * 60 'minutes' 
,x.r_start 
,x.r_end 
from 
(select r_start ,r_end 
,row_number() over (order by r_start asc) rowid 
from #t) x 
left join (select r_start ,r_end 
,row_number() over (order by r_start asc) rowid 
from #t) y 
on x.rowid = y.rowid - 1 


--returns unreserved dates 
select 
x.r_end available_from 
,y.r_start available_to 
from 
(select r_start ,r_end 
,row_number() over (order by r_start asc) rowid 
from #t) x 
left join (select r_start ,r_end 
,row_number() over (order by r_start asc) rowid 
from #t) y 
on x.rowid = y.rowid - 1 
+0

Я попробовал ваш ответ. Я получаю результат, который я не могу понять. не могли бы вы включить результат в свой ответ и объяснить его? – FLICKER

+0

отредактировал мой ответ. – Kostya

Смежные вопросы