我想从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 :(得分:0)
维护一个包含所有有效约会时间的表。在10小时内放置所有可能的1小时,30米,15米的插槽仍然很小(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
)