Need to query for users who have time conflicts, and return those time conflicts
This is a question that builds off of one of my previous questions. The tables are the same:
Users
------------------------------------
UserID | Name | Assignable
------------------------------------
5 | John开发者_C百科 Doe | 1
TimeSlots
-------------------------------------------------------
TimeSlotID | StartTime | EndTime
-------------------------------------------------------
3 | 2011-06-30 15:00:00 | 2011-06-30 16:00:00
Appointments
------------------------------------
TimeSlotID | UserID
------------------------------------
3 | 5
The accepted answer helped me find users who were available for a certain time span. I need some way to input a start date/time and an end date/time and return any TimeSlots
that conflict with those datetimes (they are in between the start/end dates, at the start/end times). But I need it to be organized by user, so:
If I input 2011-07-05
for the start date and 2011-07-07
for the end date, then I input 07:00
for the start time and 19:00
for the end time. And I have two users (User 1 and User 2), one who has no Appointments
and one who has an Appointment
on 2011-07-06 11:00
. I would need the results to be something like:
User 1: NULL
User 2: (Array ofTimeSlots
that conflict)
EDIT: Don't know if I was clear enough with the start/end dates and times. It would only look for conflicts between the start and end times on each date (inclusive) between the start and end date.
A slight modification on the previous answer - to catch those timeslots that start in your interval and end after it or start before your interval and end during it (technically still a conflict in your definition):
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
If you don't want to use concatenation, then just return each timeslot and convert the results into arrays in your php code. In this case, your SQL will be
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
MySQL cannot return arrays, but you can come close with the following:
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
This will give you a comma-separated list (or NULL) of time slots per a user.
精彩评论