2014-09-05 68 views
4

我有一個包含給定日期中可變時間範圍的保留表。它們是30分鐘,60分鐘,用戶輸入的任何給定分鐘範圍的預留時間段。SQL提取一天中未保留的所有30分鐘或60分鐘的時間段

我想要做的是創建一個SQL語句,可以給我所有的時間段在給定的一天,不保留。用戶可以指定分鐘範圍(30分鐘,60分鐘,90分鐘)。我甚至從哪裏開始?

保留表是基本的:

ROOM, RESERVED_DATE, FROM_TIME, TO_TIME 
A  09/02/2014  9:00 AM 10:00 AM 
B  09/02/2014  11:00 AM 12:00 PM 
C  09/02/2014  1:30 PM 2:00 PM 

我會允許用戶說,他們希望工作時間(8:00 AM - 4:30 PM)之間的所有可用的房間是一個特定的增量內(30分鐘,60分鐘,90分鐘)。

+2

您需要從具有所有可用時間段的表開始。然後你做一個左邊加入你的保留。 – 2014-09-05 14:43:51

+1

保留時間是否總是在30分鐘以內,或者您是否可以在9:13 - 9:43之間進行預約? – SQLChao 2014-09-05 15:13:24

+0

我會說,一般來說,他們會在一個半小時的時間內落下。他們可能會陷入宿舍,儘管這很少見。 – jlrolin 2014-09-05 17:27:11

回答

0

這是我會採取的方法。這需要您的@minimum_interval並找到一個大於此值的時間間隔。正如所寫,它不包括前後。您可以通過在表格中插入一個虛擬日期作爲開始日期/時間和結束日期/時間,或者將它建立爲cte中的聯合(首選)來解決該問題。

基本上,它所做的全部工作都是按開始時間對[to]列和[next]列進行日期排序,其中[next]用滯後函數進行計算。這使你不必擁有一張專用的表格,這也是爲什麼我要在cte中建立一個虛擬的開始和結束會議的原因;由於數據未被存儲,因此不必更新。您可以將開始和結束時間存儲在元數據結構中,以便爲不同房間設置不同的「開放」時段。

另外,您可以將PARTITION子句添加到滯後函數中,以使其無需指定房間即可工作。

這是一個有趣的練習,感謝您提出這個問題!

declare @date [datetime] = cast(current_timestamp as [date]); 
declare @minimum_interval [int] = 15 
    , @room   [sysname] = N'A'; 
declare @reservation table (
[room] [sysname] 
, [from] [datetime] 
, [to] [datetime]); 
insert into @reservation 
     ([room],[from],[to]) 
values  (N'A',N'20140902 09:00',N'20140902 10:00'), 
     (N'A',N'20140902 10:00',N'20140902 11:00'), 
     (N'A',N'20140902 13:00',N'20140902 14:00'); 
with [builder] 
as (select [room] 
      , [from] 
      , [to] 
      , lag ([from] 
        , 1 
        , 0) 
       over (
        order by [from] desc) as [next] 
    from @reservation 
    where [room] = @room) 
select [room] 
    , [from] 
    , [to] 
    , [next] 
from [builder] 
where datediff(minute 
      , [to] 
      , [next]) > @minimum_interval; 
+0

這是正確的。原來的問題沒有說明一個版本,所以我沒有理由不使用什麼是當前版本,即SQL Server 2012。 – 2014-09-08 14:14:31