开发者

Need help with this MySQL query. Finding users who are available at a certain time

Here is a simplified schema of my database:

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   

I have Users that can be assigned to TimeSlots that make up Appointments. I need a way to start with a start and end time and query all Users that are able to be assigned (Assignable flag set to 1) and have no time conflicts (Appointments that overlap) with those times.

Older TimeSlots will be in there too so you would only be interested in TimeSlots that are now or in the f开发者_C百科uture.


select *
from users u    
where u.Assignable = 1
    and u.UserID not in (
       select UserID
       from Appointments a
         join TimeSlots t on a.TimeSlotID = t.TimeSlotID 
       where t.EndTime > now()
          and t.EndTime > @desiredStartTime
          and t.StartTime < @desiredEndTime
    )

edit Taking a cue from tandu

I think this would also work, and it has the added performance benefit of no subqueries:

select *
from users u    
    left join Appointments a on a.UserID = u.UserID
    left join TimeSlots t on (
    a.TimeSlotID = t.TimeSlotID 
       and t.EndTime > now()
       and t.EndTime > @desiredStartTime
       and t.StartTime < @desiredEndTime
    )
where 
    u.Assignable = 1
    and t.TimeSlotID is null


say @start is the start time and @end is the end time, which you pass into the query in your script:

SELECT
   UserID
FROM
   Users
   NATURAL JOIN Appointments a
   NATURAL JOIN TimeSlots t1
   LEFT JOIN TimeSlots t2 ON (
      a.TimeSlotID = t2.timeSlotID
      AND (
         t2.EndTime BETWEEN @start AND @end
         OR t2.StartTime BETWEEN @start AND @end
         OR @start > t2.StartTime AND @end < t2.EndTime
      )
      AND t2.StartTime > NOW()
   )
WHERE
   Assignable
   AND NOW() < t1.StartTime
   AND t2.TimeSlotID IS NULL
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜