请参阅表格结构,查询和结果。
MeetingRoom
ID | Area | RoomNo Capacity distances
--- ----- --------- ---------- ----------
1 1 R1 10 10
2 1 R3 24 4
3 8 R4 24 4
4 1 R5 10 10
ReservationTable
ReservationID RoomID DateTimeStart DateTimeEnd
------------- ----------- ----------------------- -----------------------
1 1 2013-10-10 17:00:00.000 2013-10-10 19:00:00.000
查询
Declare @Start Datetime
Declare @End Datetime
set @Start='2013-10-10 13:00:00.000'
set @End='2013-10-10 14:00:00.000'
select
MeetingRoom.ID
from
MeetingRoom
left Join ResReservationTable Res on Res.RoomID = MeetingRoom.ID
Where
Res.DateTimeStart != @Start and Res.DateTimeEnd != @End
and (Res.DateTimeStart Not Between @Start and @End)
and (Res.DateTimeEnd Not Between @Start and @End)
此查询仅返回一条记录,因为它应返回4条记录
答案 0 :(得分:4)
如果您使用LEFT OUTER JOIN
并将WHERE clause
设置条件设置为右侧表而不是IS NULL
,则结果为INNER JOIN
。
我认为这就是你想要的。
Declare @Start Datetime
Declare @End Datetime
set @Start='2013-10-10 13:00:00.000'
set @End='2013-10-10 14:00:00.000'
select
MeetingRoom.ID
from
MeetingRoom
left Join ResReservationTable Res on Res.RoomID = MeetingRoom.ID
Where
(
Res.DateTimeStart != @Start and Res.DateTimeEnd != @End
and (Res.DateTimeStart Not Between @Start and @End)
and (Res.DateTimeEnd Not Between @Start and @End)
)
OR Res.ReservationID IS NULL
我认为你必须改写你的WHERE
条件。如果你想要完全自由的空间(即间隔不相交),你可以使用它:
WHERE
Res.DateTimeStart > @End
OR Res.DateTimeEnd < @Start
OR Res.ReservationID IS NULL
答案 1 :(得分:2)
你应该使用内部联接...... 的修改 您必须正在使用外连接,但请考虑空值与非空值的比较...
一种方法是使用OR子句
显式接受空日期值答案 2 :(得分:2)
最好的方法是将WHERE子句中的东西移动到ON子句中:
select
MeetingRoom.ID
from MeetingRoom
left Join ResReservationTable Res on Res.RoomID = MeetingRoom.ID
and Res.DateTimeStart != @Start and Res.DateTimeEnd != @End
and Res.DateTimeStart Not Between @Start and @End
and Res.DateTimeEnd Not Between @Start and @End
嘿presto,你保留外连接但仍然过滤结果,而且你现在拥有最佳性能的查询版本。
这是一个非常常见且不正确的假设,即连接条件可能只有“关键相关”表达式,但实际上您可以有任何条件,甚至是未加入表中的列上的条件。
答案 3 :(得分:2)
你能试试吗?它使用“Outer”并检查为没有保留的房间返回的NULL值,并返回这些行。
Declare @Start Datetime
Declare @End Datetime
set @Start='2013-10-10 13:00:00.000'
set @End='2013-10-10 14:00:00.000'
select
MeetingRoom.ID
from
MeetingRoom
left Outer Join ResReservationTable Res on Res.RoomID = MeetingRoom.ID
Where
(Res.DateTimeStart is NULL OR Res.DateTimeEnd is NULL)
and Res.DateTimeStart != @Start and Res.DateTimeEnd != @End
and (Res.DateTimeStart Not Between @Start and @End)
and (Res.DateTimeEnd Not Between @Start and @End)