需要查询有时间冲突的用户,并返回那些时间冲突

时间:2011-07-05 13:07:20

标签: php mysql

这是一个基于我之前的questions之一的问题。表格是相同的:

Users
------------------------------------
UserID | Name      | Assignable
------------------------------------
  5    | John Doe  |      1

TimeSlots
-------------------------------------------------------
TimeSlotID | StartTime           | EndTime
-------------------------------------------------------
     3     | 2011-06-30 15:00:00 | 2011-06-30 16:00:00

Appointments
------------------------------------
TimeSlotID | UserID
------------------------------------
     3     |    5   

接受的答案帮助我找到了一段时间内可用的用户。我需要一些方法来输入开始日期/时间和结束日期/时间,并返回与这些日期时间冲突的任何TimeSlots(它们位于开始/结束日期之间,开始/结束时间)。但是我需要它由用户组织,所以:

如果我输入2011-07-05作为开始日期,2011-07-07输入结束日期,那么我输入07:00作为开始时间,19:00作为结束日期。我有两个用户(用户1和用户2),一个没有Appointments的用户和一个Appointment 2011-07-06 11:00的用户。我需要结果如下:

用户1:NULL
用户2 :(冲突的TimeSlots数组)

编辑:不知道我是否对开始/结束日期和时间足够清楚。它只会查找开始日期和结束日期之间每个日期(包括)的开始和结束时间之间的冲突。

2 个答案:

答案 0 :(得分:1)

MySQL无法返回数组,但您可以接近以下内容:

SELECT
   UserID,
   GROUP_CONCAT(CONCAT(StartTime, ' - ', EndTime)) slots
FROM
   Users
   LEFT JOIN Appointments a USING (UserID)
   LEFT JOIN TimeSlots ts ON (
      a.TimeSlotID = ts.TimeSlotID
      AND ts.EndTime > @start
      AND ts.StartTime > @end
   )
GROUP BY
   UserID

这将为您提供每个用户的逗号分隔列表(或NULL)。

答案 1 :(得分:1)

对上一个答案稍作修改 - 抓住那些从你的间隔开始并在它之后结束或在你的间隔之前开始并在它之间结束的时间段(技术上仍然是你定义中的冲突):

SELECT
   UserID
   GROUP_CONCAT(CONCAT(StartTime, ' - ', EndTime)) slots
FROM
   Users
   LEFT JOIN Appointments a USING (UserID)
   LEFT JOIN TimeSlots ts ON (
      a.TimeSlotID = ts.TimeSlotID
      AND ( ts.EndTime > @start AND ts.StartTime > @end
            OR ts.EndTime between @start and @end
            OR ts.StartTime between @start and @end )
   )
GROUP BY
   UserID
ORDER BY
   UserID

如果您不想使用连接,那么只需返回每个时间段并将结果转换为PHP代码中的数组。在这种情况下,您的SQL将是

SELECT
   UserID,
   CONCAT(StartTime, ' - ', EndTime) slot
FROM
   Users
   LEFT JOIN Appointments a USING (UserID)
   LEFT JOIN TimeSlots ts ON (
      a.TimeSlotID = ts.TimeSlotID
      AND ( ts.EndTime > @start AND ts.StartTime > @end
            OR ts.EndTime between @start and @end
            OR ts.StartTime between @start and @end )
   )
ORDER BY
   UserID, StartTime