2012-11-19 27 views
1

背景(非常簡化): 我有在網站上銷售的橫幅空間。橫幅可以預定給定的開始和結束日期,這個橫幅不能被雙重預訂。該橫幅一年內可以多次預訂,但在同一天不能超過一次。確定給定開始日期和結束日期之間的可用日期範圍

我的問題: 保存預訂時,用戶輸入開始/結束日期,現在可以在此開始/結束日期內多次預訂橫幅,並且我想自動預訂開始/結束時的任何空閒日期日期。

一個例子:

s|aaaaaaa|s1------e1|aaaaaaaaa|s2------e2|aaaaaa|e 

S/e。通過用戶輸入 =預訂日期。 s1 - e1 =首次預訂。 s2 - e2 =第二次預訂。 aaa .. =可用日期範圍。

在tsql中,我想找出aaa ..(可用日期範圍)的開始/結束日期。然後將它們插入到預訂表中。

預訂表看起來像這樣:

BookingId------BannerId-----StartDate-----ExpiryDate 
000000001------00000001-----2012-11-01----2012-11-05 
000000002------00000001-----2012-11-10----2012-11-15 
000000003------00000001-----2012-11-16----2012-11-20 
000000004------00000001-----2012-12-01----2012-12-05 

所以,如果一個用戶進入的2012年11月4日開始日期和二○一二年十二月一十日結束日期。可用日期爲2012-11-06至2012-11-09,2012-11-21至2012-11-30,2012-12-06-2012-12-10。

感謝您有關如何做到這一點的任何建議。

回答

1

這似乎這樣的伎倆:

(所有一個腳本,而是分裂,這樣你可以看到每個部分)的數據設置:

declare @Bookings table (
BookingId char(9) not null, 
BannerId char(8) not null, 
StartDate date not null, 
ExpiryDate date not null 
) 
insert into @Bookings (BookingId,BannerId,StartDate,ExpiryDate) values 
('000000001','00000001','20121101','20121105'), 
('000000002','00000001','20121110','20121115'), 
('000000003','00000001','20121116','20121120'), 
('000000004','00000001','20121201','20121205') 

輸入:

declare @StartDate date 
declare @EndDate date 
select @StartDate = '20121104',@EndDate = '20121210' 

查詢:

;With Ordered as (
    select *,ROW_NUMBER() OVER (PARTITION BY BannerID ORDER BY StartDate) as rn 
    from @Bookings 
), FreePeriods as (
    select 
     o1.BannerId, 
     DATEADD(day,1,o1.ExpiryDate) as StartDate, 
     DATEADD(day,-1,o2.StartDate) as EndDate 
    from 
     Ordered o1 
      inner join 
     Ordered o2 
      on 
       o1.BannerId = o2.BannerId and 
       o1.rn = o2.rn - 1 
    where 
     DATEDIFF(day,o1.ExpiryDate,o2.StartDate) >= 3 
    union all 
    select 
     BannerId,'00010101',DATEADD(day,-1,MIN(StartDate)) from @Bookings group by BannerID 
    union all 
    select 
     BannerID,DATEADD(day,1,MAX(ExpiryDate)),'99991231' from @Bookings group by BannerID 
) 
select 
    BannerID, 
    CASE WHEN @StartDate > StartDate then @StartDate ELSE StartDate END as StartDate, 
    CASE WHEN @EndDate < EndDate then @EndDate ELSE EndDate END as EndDate 
from 
    FreePeriods fp 
where 
    fp.EndDate >= @StartDate and 
    fp.StartDate <= @EndDate 

Basic盟友,我組織的訂單日期成對,然後使用每一對來構建一個存在於他們之間的自由時期。我還僞造了兩個時期 - 一個從時間的開始到最早的預訂,一個從最新的預訂到最後一個。

然後,我在最後一個查詢中找到與請求日期重疊的時間段,並使用一些CASE表達式來修改超出請求日期的時間段。

+0

哇,我已經測試了這幾個日期,似乎工作得很好。我也學到了一些東西。謝謝達米安。 – WooHoo

相關問題