2014-01-17 42 views
0

我想获得的可用时间列表中指定的日期和持续时间构成tblAppointments表预约可用时间

tblAppointments 

id int 
BookingDate datetime 
BookedStartTime datetime 
BookedEndTime datetime 

样本数据表中的

id BookingDate   BookedStartTime  BookedEndTime 
1 2014-02-03 00:00:00 2014-02-03 08:30:00 2014-02-03 09:00:00 
2 2014-02-03 00:00:00 2014-02-03 09:00:00 2014-02-03 10:30:00 
3 2014-02-03 00:00:00 2014-02-03 12:00:00 2014-02-03 14:30:00 
4 2014-02-03 00:00:00 2014-02-03 15:00:00 2014-02-03 16:30:00 

如果我给一个输入参数为

BookingDate : 2014-02-03  
DurationCode : 1 (eg 30 minutes) 

我想得到如下结果

2014-02-03 08:00:00  2014-02-03 08:30:00 
2014-02-03 10:30:00  2014-02-03 11:00:00 
2014-02-03 11:00:00  2014-02-03 11:30:00 
2014-02-03 11:30:00  2014-02-03 12:00:00 
2014-02-03 14:30:00  2014-02-03 15:00:00 
2014-02-03 16:30:00  2014-02-03 17:00:00 

如果输入参数

BookingDate : 2014-02-03  
DurationCode : 2 (eg 15 minutes) 

结果应该像下面给出

2014-02-03 08:00:00  2014-02-03 08:15:00 
2014-02-03 08:15:00  2014-02-03 08:30:00 
2014-02-03 10:30:00  2014-02-03 10:45:00 
2014-02-03 10:45:00  2014-02-03 11:00:00 
2014-02-03 11:00:00  2014-02-03 11:15:00 
2014-02-03 11:15:00  2014-02-03 11:30:00 
2014-02-03 11:30:00  2014-02-03 11:45:00 
2014-02-03 11:45:00  2014-02-03 12:00:00 
2014-02-03 14:30:00  2014-02-03 14:45:00 
2014-02-03 14:45:00  2014-02-03 15:00:00 
2014-02-03 16:30:00  2014-02-03 16:45:00 
2014-02-03 16:45:00  2014-02-03 17:00:00 

的开始和结束的任命是08:00至18:00

我写了一个相同的存储过程,似乎正在工作,但我想知道是否有任何简单的方法来做同样的事情。

存储过程是

ALTER Procedure [dbo].[FindAvailableTime] (
    @BookingDate datetime, 
    @DurationCode int 
) 
as 
Declare @Duration datetime 
Declare @DurationMinutes int 
Declare @DurationHours int 

select @Duration = Duration from DurationCode where DurationCodeID = @DurationCode 

Set @DurationMinutes = datepart(minute,@Duration) 
Set @DurationHours = datepart(hour,@Duration) 
if (@DurationHours > 0) 
Begin 
Set @DurationMinutes = @DurationMinutes + (@DurationHours * 60) 
End 

Declare @StartTimeHR int 
Declare @StartTimeMN int 
Declare @EndTimeHR int 
Declare @EndTimeMN int 

Declare @CurrentDateTimeStart datetime 
Declare @CurrentDateTimeStartString varchar(100) 
Declare @CurrentDateTimeEnd datetime 
Declare @CurrentDateTimeEndString varchar(100) 
Declare @CurrentDateTimeEndWork datetime 
Declare @CurrentDateTimeEndStringWork varchar(100) 


Declare @CurrentYear int 
Declare @CurrentMonth int 
Declare @CurrentDay int 

Set @CurrentYear = datepart(year,@BookingDate) 
Set @CurrentMonth = datepart(month,@BookingDate) 
Set @CurrentDay = datepart(day,@BookingDate) 

Set @StartTimeHR = 8 
Set @StartTimeMN = 0 
Set @EndTimeHR = 18 
Set @EndTimeMN = 1 
Set @CurrentDateTimeStartString = convert(varchar(10),@CurrentYear) + '-' + convert(varchar(10),@CurrentMonth) + '-' + convert(varchar(10),@CurrentDay) + ' ' + convert(varchar(10),@StartTimeHR) + ':' + convert(varchar(10),@StartTimeMN) + ':' + '0' 
Set @CurrentDateTimeEndString = convert(varchar(10),@CurrentYear) + '-' + convert(varchar(10),@CurrentMonth) + '-' + convert(varchar(10),@CurrentDay) + ' ' + convert(varchar(10),@EndTimeHR) + ':' + convert(varchar(10),@EndTimeMN) + ':' + '0' 
set @CurrentDateTimeStart = convert(datetime, @CurrentDateTimeStartString) 
set @CurrentDateTimeEnd = convert(datetime, @CurrentDateTimeEndString) 

Declare @CurrentDateTimeEndTemp datetime 
set @CurrentDateTimeEndTemp = dateadd(mi,@DurationMinutes,@CurrentDateTimeStart) 

Declare @AppointmentStartTime datetime 
Declare @AppointmentEndTime datetime 

Declare @StartDate datetime 
Declare @EndDate datetime 
Declare @EndDateTemp datetime 

Declare @StartDatePlusOne datetime 
Declare @EndDateMinusOne datetime 

set @StartDate = @CurrentDateTimeStart 
set @EndDate = @CurrentDateTimeEnd 
set @EndDateTemp = dateadd(mi,@DurationMinutes,@StartDate) 

Set @StartDatePlusOne = dateadd(mi,1,@StartDate) 
Set @EndDateMinusOne = DateAdd(mi,-1,@EndDateTemp) 

Create Table #Appointment_AvailableTime (StartTime datetime, EndTime datetime) 

if Exists (select * from tblAppointments where BookingDate = @BookingDate) 
Begin 
while (@EndDateTemp < @EndDate) 
Begin 
    if not exists (Select * from tblAppointments where @StartDatePlusOne between BookedStartTime and BookedEndTime or @EndDateMinusOne between BookedStartTime and BookedEndTime) 
    begin 
     if not exists (Select * from tblAppointments where BookedStartTime Between @StartDatePlusOne and @EndDateMinusOne or BookedEndTime between @StartDatePlusOne and @EndDateMinusOne) 
      Begin 
      insert into #Appointment_AvailableTime values(@StartDate, @EndDateTemp) 
      set @StartDate = dateadd(mi,@DurationMinutes,@StartDate) 
      End 
     Else 
      Begin 
      Select @StartDate = max(BookedEndTime) from tblAppointments where BookedStartTime Between @StartDatePlusOne and @EndDateMinusOne or BookedEndTime between @StartDatePlusOne and @EndDateMinusOne 
      End 

      set @EndDateTemp = dateadd(mi,@DurationMinutes,@StartDate) 
      Set @StartDatePlusOne = dateadd(mi,1,@StartDate) 
      Set @EndDateMinusOne = DateAdd(mi,-1,@EndDateTemp) 
    End 
    Else 
    Begin 
     Select @StartDate = max(BookedEndTime) from tblAppointments where @StartDatePlusOne between BookedStartTime and BookedEndTime or @EndDateMinusOne between BookedStartTime and BookedEndTime 
     set @EndDateTemp = dateadd(mi,@DurationMinutes,@StartDate) 
     Set @StartDatePlusOne = dateadd(mi,1,@StartDate) 
     Set @EndDateMinusOne = DateAdd(mi,-1,@EndDateTemp) 
    End 
End 
End 
Else 
Begin 
Set @CurrentDateTimeEndWork = dateadd(mi,@DurationMinutes,@CurrentDateTimeStart) 
while (@CurrentDateTimeStart < @CurrentDateTimeEnd and @CurrentDateTimeEndWork < @CurrentDateTimeEnd) 
Begin 
    insert into #Appointment_AvailableTime values(@CurrentDateTimeStart, @CurrentDateTimeEndWork) 
    set @CurrentDateTimeStart = dateadd(mi,@DurationMinutes,@CurrentDateTimeStart) 
    Set @CurrentDateTimeEndWork = dateadd(mi,@DurationMinutes,@CurrentDateTimeStart) 
End 
End 
select StartTime, EndTime from #Appointment_AvailableTime 

感谢

回答

0

维持持有所有有效预约时间的表。在10小时内放置所有可能的1h,30m,15m插槽仍然很小(70行)。这使得添加更复杂的规则,比如“下午4点以后不需要1小时的任命”非常容易。在查找表中添加星期几列可以让您轻松添加诸如“在星期三延长时间”或“半天星期六”之类的内容。

CREATE TABLE tblAppointmentSlots (
    DurationID int, 
    SlotStartTime datetime CHECK (CAST(SlotStartTime AS int) = 0), 
    SlotEndTime datetime CHECK (CAST(SlotEndTime AS int) = 0) 
) 
GO 

INSERT tblAppointmentSlots VALUES 
(1, '08:00', '08:30'), 
(1, '08:30', '09:00'), 
etc.. 
GO 

ALTER Procedure [dbo].[FindAvailableTime] (
    @BookingDate datetime, 
    @DurationCode int 
) 
AS 
SELECT 
    @BookingDate + SlotStartTime, 
    @BookingDate + SlotEndTime 
FROM tblAppointmentSlots 
WHERE DurationID = @DurationCode 
    AND NOT EXISTS (
    SELECT 1 
    FROM tblAppointments 
    WHERE @BookingDate + SlotStartTime < BookedEndTime 
     AND @BookingDate + SlotEndTime > BookedStartTime 
)