SQL - 查询会议室

时间:2014-02-24 01:10:11

标签: mysql sql sql-server tsql

如果所选时间段已在会议室中召开会议,我需要一个帮助来创建一个要返回的查询。

我的表rep_reuniao具有以下设计

  ID           --> int
  ROOM         --> int
  DATE_BEGIN   --> DATETIME
  DATE_END     --> DATETIME

现在在表rep_reuniao中插入一行就像这样

 ID            --> 1
 ROOM          --> 2
 DATE_BEGIN    --> 2014-02-21 17:00:00
 DATE_END      --> 2014-02-21 18:00:00

我将创建一个Jquery Ajax脚本,根据所选的日期时间返回truefalse JSON响应。

因此,查询将采用格式为ROOMDATE_BEGIN的{​​{1}},2014-02-21 17:00格式DATE_END

我已经检查了另一个回复,但其中大部分是查询以显示可用的房间。在我的设计中,一个房间总是可用的,除非在表格中存在登记册。

2014-02-21 18:00

Example 1 1

已经使用了2014-02-21 17:00:00个房间2014-02-21 18:00:00

如果用户在以下位置选择房间,则需要创建一个返回值(Anything)的查询:

BEGIN = 2012-02-21 16:30:00 
END = 2012-02-21 17:30:00

请参阅?表中使用的房间从17:00开始,所以今天我的查询很容易返回一个值,如果用户选择的开始是相同的。但是,用户选择的结束日期介于已使用的时间之间。

嗯,用户选择的时间无法使用,请查看开始日期和结束日期。我现在没有想法,有人可以帮助我吗?

您需要检查一个日期范围是否与另一个日期范围重叠。

New Date Range =               |-----------|
Test1          =      |=====|
Test2          =            |=====|
Test3          =                  |=====|
Test4          =                        |=====|
Test5          =                              |=====|
Test6          =            |=================|

只有Test1和Test5不重叠。

抱歉,如果有任何英文错误。如果有人能够解决,我会很感激。

3 个答案:

答案 0 :(得分:4)

重叠时间帧的正确逻辑是,当这两个条件都为真时,两个时间帧重叠:

  • 第一个在另一个结束之前开始
  • 另一个开始后的第一个结束

在SQL中,这些可以很容易地表达出来:

SELECT r.* 
FROM rep_reuniao r
WHERE @UserBegin <= r.DATE_END AND
      @UserEnd >= r.DATE_BEGIN;

请注意,如果在指定的时间范围内发生多个会议,则会返回多行。

如果您想要true / false或0/1,请使用聚合和case

SELECT (case when count(*) = 0 then 'false' else 'true' end) as HasOverlappingRooms
FROM rep_reuniao r
WHERE @UserBegin <= r.DATE_END AND
      @UserEnd >= r.DATE_BEGIN;

答案 1 :(得分:0)

如果查询返回任何意味着已预订房间的行,请尝试此操作。 一个简单的解释是,用户需要@UserBegin@UserEnd时间才能获得房间。

如果@UserBegin位于行的开头和结尾之间,那么它已经被预订了。

同样,如果@UserEnd位于行的开头和结尾之间,即使这样,也会预订房间。

SELECT * 
FROM rep_reuniao r
WHERE (@UserBegin BETWEEN r.DATE_BEGIN AND r.DATE_END)
    OR (@UserEnd BETWEEN r.DATE_BEGIN AND r.DATE_END)
    OR (@UserBegin <= r.DATE_BEGIN AND @UserEnd >= r.DATE_END)

从这里你可以扩展它以返回如图所示的bool

SELECT CASE WHEN EXISTS ( /* The above query */ ) THEN 0 ELSE 1 

当房间可用或不可用时,应该返回1或0。

答案 2 :(得分:0)

您可以尝试以下查询。当表格中的日期落在您的范围内,或者当您的范围落在表格中的日期范围内时,它应该会捕获:

SELECT CASE WHEN COUNT(*) > 1 THEN 1 ELSE 0 END AS AlreadyBooked
FROM rep_reuniao r
WHERE (@UserBegin BETWEEN r.DATE_BEGIN AND r.DATE_END)
    OR (r.DATE_BEGIN BETWEEN @UserBegin AND @UserEnd)

查询会检查@UserBegin落在行范围内或行的开始日期落在@userBegin - @UserEnd的任何行。它会找到范围部分重叠的情况,或者哪个范围落在另一个范围内的情况。