Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
In a scheduling application, it may be desirable to find the first available schedule time (timeslot) for a new appointment. The new appointment must fit completely between existing appointments -without overlap. As the schedule fills, new entries are assigned to the next first available schedule time (timeslot). Alternatively, if desired, the first n available timeslots will be returned for selection.
In the sample data below, the Schedule table is pre-filled with a Start of Day record, and an End of Day record. Normally, that information would be derived from a JOIN with a Calendar table.
A solution for SQL Server 2005 / SQL Server 2008 is provided below.
Create Sample Data
-- Suppress data loading messages
SET NOCOUNT ON
DECLARE @Schedule table
( AppID int IDENTITY,
AppTeam varchar(20),
AppStart datetime,
AppFinish datetime
)
INSERT INTO @Schedule VALUES ( 'Start', NULL, '01/11/2007 09:00' )
INSERT INTO @Schedule VALUES ( 'Smith', '01/11/2007 09:00', '01/11/2007 09:30' )
INSERT INTO @Schedule VALUES ( 'Smith', '01/11/2007 10:00', '01/11/2007 10:15' )
INSERT INTO @Schedule VALUES ( 'Jones', '01/11/2007 11:00', '01/11/2007 12:00' )
INSERT INTO @Schedule VALUES ( 'Williams', '01/11/2007 12:00', '01/11/2007 14:45' )
INSERT INTO @Schedule VALUES ( 'Hsiao', '01/11/2007 15:30', '01/11/2007 16:00' )
INSERT INTO @Schedule VALUES ( 'Lopez', '01/11/2007 16:00', '01/11/2007 17:30' )
INSERT INTO @Schedule VALUES ( 'Green', '01/11/2007 17:30', '01/11/2007 18:30' )
INSERT INTO @Schedule VALUES ( 'Alphonso', '01/11/2007 20:00', '01/11/2007 20:30' )
INSERT INTO @Schedule VALUES ( 'End', '01/11/2007 21:00', NULL )
SQL Server 2005 / SQL Server 2008 Solution
-- Determine the Length of Time Required
DECLARE @AppNeed int
SET @AppNeed = 45
--Find FIRST Available Time Slot
;WITH CTE
AS ( SELECT
*,
RowNumber = ROW_NUMBER() OVER( ORDER BY AppStart ASC )
FROM @MySchedule
)
SELECT FirstApptAvail = min( a.AppFinish )
FROM CTE a
INNER JOIN CTE b
ON a.RowNumber = b.RowNumber - 1
WHERE datediff( minute, a.AppFinish, b.AppStart) >= @AppNeed
FirstApptAvail |
---|
2007-01-11 10:15:00.000 |
--Find All Available Time Slots
;WITH CTE
AS ( SELECT
*,
RowNumber = ROW_NUMBER() OVER( ORDER BY AppStart ASC )
FROM @MySchedule
)
SELECT TOP 3 ApptOptions = a.AppFinish
FROM CTE a
INNER JOIN CTE b
ON a.RowNumber = b.RowNumber - 1
WHERE datediff( minute, a.AppFinish, b.AppStart) >= @AppNeed
AppOptions |
2007-01-11 10:15:00.000 |
2007-01-11 14:45:00.000 |
2007-01-11 18:30:00.000 |
Additional Resources
Having a Calendar table is a very useful utility table that can benefit many data querying situations. For this example, two additional columns (AppStart, AppFinish) can be added to the table to handle situations where business hours are not the same for all days.
See Also
- SQL Server Query Language - Transact SQL
- [[SQL Server 2012]]
- [[SQL Server Developer Resources]]