Sql Query连接表中的问题

时间:2014-04-18 16:01:05

标签: sql sql-server join

我正在使用两个表tblMeet(roomid,meetid,timein,timeout,roomname,user,date)tblMeetRoom(roomid,roomname,pc,phone,projector,capacity,location),其中roomid,roomnametblMeet中的外键。

我需要的是:  从tblMeet中选择所有这样的roomid,其中date = sysdate,time in和time out不与传递的参数重叠,并且具有用户(pc,phone,projector)提供的参数中指定的资源,然后我需要来自tblMeetRoom的剩余未分配的房间(如果有这样的房间)。任何分配的房间都会填充tblMeet,而当创建房间信息时,它会填充tblMeetingRoom。

我为此创建了这个存储过程: 参数:paramdate,paramtimein,paramtimeout,paramdate,parampc,paramphone,paramprojector

select roomname
from tblmeet 
where
    (date=paramdate 
    and (paramtimein not between (timein and timeout))
    and paramtimeout not between(timein and timeout)))
except 
    select roomname
    from tblmeet
    where (date=paramdate
           and (paramtimein between (timein and timeout))
           and paramtimeout between(timein and timeout))
union

select roomname
from tblmeetroom
where(phone=paramphone
      and pc=parampc
      and projector=paramprojector)
except
    select roomname 
    from tblmeetroom 
    where(date=paramdate 
          and (paramtimein not between (timein and timeout))
          and paramtimeout not between(timein and timeout)))    

然而,我得到的结果是,不是划掉时间间隔重叠的分配房间,而是重新调整房间,其中paramtimein和paramtimeout严格地在timein和time out的colum值之间。也就是说,如果有一个房间已经分配给11:30到12:45,如果paramtimein和paramtimeout像11:45到12:30那样会被预订,但是如果paramtimein和paramtimeout就像是11:45到12 :50,这仍然显示这个房间可用......

请帮助解决可能出现的任何逻辑错误。谢谢。

1 个答案:

答案 0 :(得分:0)

没有花时间完全理解问题,我怀疑你对重叠时间范围的测试是有缺陷的。您正在检查您的开始和停止时间两者在您检查的开始和停止时间内的任何冲突。如果它们两者在该范围内,那么您只会发现冲突,其中您的测试范围完全在现有范围内。如果您希望任何重叠,则只需要在现有范围结束之前要求测试范围开始,并且测试范围在现有范围开始后结束。这很难解释,但代码实际上比BETWEEN概念要短。请参阅此示例,该示例不能解决您的整个问题集,而只关注在给定所需时间范围内查找可用空间。

DECLARE @tblmeet TABLE (roomname varchar(50), timein datetime, timeout datetime);
DECLARE @paramtimein datetime, @paramtimeout datetime;
INSERT INTO @tblmeet (roomname, timein, timeout) values ('A', '2014-04-18 9:00 AM','2014-04-18 9:14 AM');
INSERT INTO @tblmeet (roomname, timein, timeout) values ('A', '2014-04-18 9:15 AM','2014-04-18 9:45 AM');
INSERT INTO @tblmeet (roomname, timein, timeout) values ('B', '2014-04-18 9:00 AM','2014-04-18 9:29 AM');
INSERT INTO @tblmeet (roomname, timein, timeout) values ('B', '2014-04-18 9:30 AM','2014-04-18 10:29 AM');
INSERT INTO @tblmeet (roomname, timein, timeout) values ('B', '2014-04-18 10:30 AM','2014-04-18 11:29 AM');
INSERT INTO @tblmeet (roomname, timein, timeout) values ('C', '2014-04-18 10:00 AM','2014-04-18 10:29 AM');
INSERT INTO @tblmeet (roomname, timein, timeout) values ('C', '2014-04-18 11:00 AM','2014-04-18 11:29 AM');

-- test input:

SELECT
    @paramtimein = '2014-04-18 9:15 AM',
    @paramtimeout = '2014-04-18 9:45 AM';

-- conflicts:

SELECT
    *
FROM        @tblmeet
WHERE       (
                @paramtimein <= timeout
            AND
                @paramtimeout >= timein
            );

-- available rooms:

SELECT
    roomname
FROM        @tblmeet

EXCEPT

SELECT
    roomname
FROM        @tblmeet
WHERE       (
                @paramtimein <= timeout
            AND
                @paramtimeout >= timein
            );

请注意,我没有考虑边缘情况。例如,如果系统在上午10:30到11:00会议时允许11:00 AM到11:30 AM会议?从技术上讲,上午11点的时间是重叠,但人们通常不认为是重叠。

此外,我会指出,您似乎要求房间有一些现有的预订,以便考虑将来预订。看起来你应该只是在某个地方有一个房间名单。考虑到所提供的信息,也许我还没有完全理解你的设计。