Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
Author |
Topic |
familysupportdba
Starting Member
2 Posts |
Posted - 2007-05-04 : 15:40:20
|
I need to be able to return a list of available rooms for a particular time slot within a date range. Also, within that date range, I want to be able to further refine the query to allow users to limit it to one or more days of the week, and to be able to filter the list of rooms by one or more building codes.I have two tables,rooms CREATE TABLE [rooms] ( [room_id] [int] NOT NULL , [room_short] [varchar] (40) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL , [room_long] [varchar] (80) COLLATE SQL_Latin1_General_CP1_CI_AS NULL , CONSTRAINT [rooms_pk] PRIMARY KEY CLUSTERED ( [room_id] ON [PRIMARY] ) ON [PRIMARY]GOsample data room_id room_short room_long ----------- ---------------------------------------- -------------------------------------------------------------------------------- 86 ASM FSSKICOLL Catskills Ski Mountain French Swiss Ski Lodge20 BLIC 114 Brokaw Library and Information Center 11491 BM 460 Best Music Center 460413 CAP 108 Chemo/Astro/Psycho 108498 CH 5 Coffee House 5453 CW 8 Candy Wilson House 879 DH 105 Dilbert House 105110 DL 237 Dough Library 237106 ED 100C Egbert Duncan House 100C68 EDA 212 Egbert Duncan Annex 21269 EH B1 East House B1113 GH AUD Green House Auditorium124 HCC 11 John M. Holmes Consultation Center 11143 HW 102 Howard Whey House 102493 JET 387 Jason E. Thomas House 38710 KB FLD Beer Brewer Stadium Field164 KS 9 W. Korn Scorn House 9198 LLA 223 Living Loving Academic Ctr 22319 LLR 421 Living Loving Residential Ctr 421530 MAB 129 Queen Mab Building 129497 NH CR Netrebko House Conference Room83 OFH WR Our Field Hall Weight Room381 OLC 5 Oil Library Classroom 595 PRH 106 Psycho Research Hall Room 10673 PSU WR Plammins Strength Union Weight Room66 QC AER Quinn the Eskimo Aerobic Area25 RH 4060 Rail House 4060608 SRC 202 Strength Recreation Center Room 202501 SRC TRK Strength Recreation Center Room 208/Track315 VG 1A Victory Gymnasium 1A75 VG NB Victory Gymnasium North Balcony329 WA 103A Walker House 103A330 WA 103B Walker House 103Band sp_reservationsCREATE TABLE [sp_reservations] ( [rsrv_id] [int] NOT NULL , [room_id] [int] NOT NULL , [rsrv_start_dt] [datetime] NOT NULL , [rsrv_end_dt] [datetime] NOT NULL , CONSTRAINT [sp_reservations_pk] PRIMARY KEY CLUSTERED ( [rsrv_id], [room_id] ON [PRIMARY] ) ON [PRIMARY]GOsample datarsrv_id room_id rsrv_start_dt rsrv_end_dt ----------- ----------- ------------------------------------------------------ ------------------------------------------------------ 2343023 20 2007-02-01 09:30:00.000 2007-02-01 10:45:00.0002352843 20 2007-02-01 11:00:00.000 2007-02-01 12:15:00.0002287765 66 2007-02-01 08:00:00.000 2007-02-01 08:50:00.0002288041 66 2007-02-01 09:00:00.000 2007-02-01 09:50:00.0002288179 66 2007-02-01 10:00:00.000 2007-02-01 10:50:00.0002289085 66 2007-02-01 10:00:00.000 2007-02-01 10:50:00.0002288110 66 2007-02-01 11:00:00.000 2007-02-01 11:50:00.0002289154 66 2007-02-01 11:00:00.000 2007-02-01 11:50:00.0002287972 66 2007-02-01 11:00:00.000 2007-02-01 12:15:00.0002289964 66 2007-02-01 11:00:00.000 2007-02-01 12:15:00.0002287869 66 2007-02-01 12:00:00.000 2007-02-01 12:50:00.0002289998 66 2007-02-01 12:30:00.000 2007-02-01 13:20:00.0002290323 66 2007-02-01 13:00:00.000 2007-02-01 13:50:00.0002259547 69 2007-02-01 09:30:00.000 2007-02-01 10:45:00.0002256054 69 2007-02-01 14:00:00.000 2007-02-01 15:15:00.0002266991 79 2007-02-01 09:30:00.000 2007-02-01 10:45:00.0002266442 79 2007-02-01 11:00:00.000 2007-02-01 12:15:00.0002266784 79 2007-02-01 14:00:00.000 2007-02-01 15:15:00.0002267352 79 2007-02-01 17:30:00.000 2007-02-01 20:20:00.0002293139 83 2007-02-01 09:30:00.000 2007-02-01 10:45:00.000So I created a calendar table:CREATE TABLE [calendar2] ( [day_date] [smalldatetime] NOT NULL , [day_of_week] [int] NOT NULL , CONSTRAINT [PK_calendar2] PRIMARY KEY CLUSTERED ( [day_date] ON [PRIMARY] ) ON [PRIMARY]GOwith smalldatetime values for every 15-minute time slot and the weekday (dw) datepart value that corresponds to the day of the week for that time slot.day_date day_of_week ------------------------------------------------------ ----------- 2007-02-01 00:00:00 52007-02-01 00:15:00 52007-02-01 00:30:00 52007-02-01 00:45:00 52007-02-01 01:00:00 52007-02-01 01:15:00 52007-02-01 01:30:00 52007-02-01 01:45:00 52007-02-01 02:00:00 52007-02-01 02:15:00 52007-02-01 02:30:00 52007-02-01 02:45:00 52007-02-01 03:00:00 52007-02-01 03:15:00 52007-02-01 03:30:00 52007-02-01 03:45:00 52007-02-01 04:00:00 52007-02-01 04:15:00 52007-02-01 04:30:00 52007-02-01 04:45:00 5 here is my sql code so farSELECT CAST((REPLACE(iq.room_short,SUBSTRING(iq.room_short,CHARINDEX(' ',iq.room_short)+1,10),'')) AS varchar(6)) as Building, cast(SUBSTRING(iq.room_short,CHARINDEX(' ', iq.room_short)+1, 10) AS varchar(10)) as Room, cast(iq.room_long as varchar(50)) as Description,from (select r.room_short, r.room_longFROM rooms r where r.room_id not in (--inner querySELECT distinct r.room_id FROM calendar2 c INNER JOIN sp_reservations sp ON c.day_date BETWEEN sp.rsrv_start_dt AND sp.rsrv_end_dt INNER JOIN rooms r ON sp.room_id = r.room_id where c.day_of_week in (1,2) --weekday (dw) datepart value(s)and DateAdd(d, DateDiff(d, 0, c.day_date), 0) <= '02/01/2007' --end of the date rangeand DateAdd(d, DateDiff(d, 0, c.day_date), 0) >= '02/01/2007' --beginning of the date rangeand convert(varchar(8), day_date, 108) <= convert(smalldatetime,convert(varchar(8),'06:15:00',8)) --end of the desired time slotand convert(varchar(8), day_date, 108) >= convert(smalldatetime,convert(varchar(8),'06:00:00',8)) --beginning of the desired time slot) ) iq where CAST((REPLACE(iq.room_short,SUBSTRING(iq.room_short,CHARINDEX(' ',iq.room_short)+1,10),'')) AS varchar(6)) in ('CW','BM') --filter the list of rooms by one or more building codesIt works ok for the most part, though I have found at least one flaw: if a user selects one or more days of the weekOUTSIDE the bounds of the date range, the inner query returns an empty set, causing the entire query to erroneouslyindicate that ALL rooms are available.Any ideas on something more accurate and efficient?BTW, the users will eventually query the database via a web interface...Thanks |
|
jshepler
Yak Posting Veteran
60 Posts |
Posted - 2007-05-07 : 23:09:29
|
In other words, you want a list of rooms that do not have an entry in the reservations table for the specified timeslot range in the specified date range.That suggests a NOT EXISTS.How about something likeDECLARE @startDate datetime, @endDate datetime, @startTime datetime, @endTime datetimeSET @startDate = dateadd(d, datediff(d, 0, @passedStartDate), 0) -- strip time (sets to midnight)SET @endDate = dateadd(d, datediff(d, 0, @passedEndDate) + 1, 0) -- add 1 day to get midnight of next daySET @startTime = dateadd(d, -datediff(d, 0, @passedStartTime), @passedStartTime) -- strip date (sets to min date)SET @endTime = dateadd(d, -datediff(d, 0, @passedEndTime), @passedEndTime)SELECT ...FROM Rooms rWHERE NOT EXISTS ( SELECT * FROM sp_reservations WHERE room_id = r.room_id AND rsrv_start_dt >= @startDate AND rsrv_end_dt < @endDate AND dateadd(d, -datediff(d, 0, rsrv_start_dt), rsrv_start_dt) >= @startTime AND dateadd(d, -datediff(d, 0, rsrv_end_dt), rsrv_end_dt) < @endTime ) /jeff |
 |
|
familysupportdba
Starting Member
2 Posts |
Posted - 2007-05-09 : 07:58:59
|
thanks!users also will want to specify a date range and say, check only the Fridays within the range for an available time slot (6am-6:15am, for example) any ideas on how to return an error if a user selects one or more days of the week OUTSIDE the bounds of the date range - say, if the range includes Monday through Tuesday and they choose a Friday? currently (in my code) if a user does that, the inner query returns an empty set, causing the entire query to erroneously indicate that ALL rooms are available. |
 |
|
|
|
|
|
|