我长期以来一直坚持这个问题。我总是接近但不准确。看起来很简单。需要在表中查找显示所有可用时隙的行,这些时隙不会与安排了appts的表中的任何行重叠。我们需要计算机自动填充没有重叠的计划。
mysql> select * from existingApptsToNotOverlap order by startTime;
+---------------------+---------------------+
| startTime | endTime |
+---------------------+---------------------+
| 2015-05-28T10:30:00 | 2015-05-28T12:15:00 |
| 2015-05-29T10:15:00 | 2015-05-29T10:45:00 |
| 2015-05-29T11:00:00 | 2015-05-29T11:45:00 |
| 2015-05-29T12:00:00 | 2015-05-29T12:45:00 |
+---------------------+---------------------+
4 rows in set (0.00 sec)
mysql> select * from allAvailableSlots;
+---------------------+---------------------+
| startTime | endTime |
+---------------------+---------------------+
| 2015-05-28T09:00:00 | 2015-05-28T09:45:00 |
| 2015-05-28T09:15:00 | 2015-05-28T10:00:00 |
| 2015-05-28T09:30:00 | 2015-05-28T10:15:00 |
| 2015-05-28T09:45:00 | 2015-05-28T10:30:00 |
| 2015-05-28T10:00:00 | 2015-05-28T10:45:00 |
| 2015-05-28T10:15:00 | 2015-05-28T11:00:00 |
| 2015-05-28T10:30:00 | 2015-05-28T11:15:00 |
| 2015-05-28T10:45:00 | 2015-05-28T11:30:00 |
| 2015-05-28T11:00:00 | 2015-05-28T11:45:00 |
| 2015-05-29T09:00:00 | 2015-05-29T09:45:00 |
| 2015-05-29T09:15:00 | 2015-05-29T10:00:00 |
| 2015-05-29T09:30:00 | 2015-05-29T10:15:00 |
| 2015-05-29T09:45:00 | 2015-05-29T10:30:00 |
| 2015-05-29T10:00:00 | 2015-05-29T10:45:00 |
| 2015-05-29T10:15:00 | 2015-05-29T11:00:00 |
| 2015-05-29T10:30:00 | 2015-05-29T11:15:00 |
| 2015-05-29T10:45:00 | 2015-05-29T11:30:00 |
| 2015-05-29T11:00:00 | 2015-05-29T11:45:00 |
| 2015-05-30T09:00:00 | 2015-05-30T09:45:00 |
| 2015-05-30T09:15:00 | 2015-05-30T10:00:00 |
| 2015-05-30T09:30:00 | 2015-05-30T10:15:00 |
| 2015-05-30T09:45:00 | 2015-05-30T10:30:00 |
| 2015-05-30T10:00:00 | 2015-05-30T10:45:00 |
| 2015-05-30T10:15:00 | 2015-05-30T11:00:00 |
| 2015-05-30T10:30:00 | 2015-05-30T11:15:00 |
| 2015-05-30T10:45:00 | 2015-05-30T11:30:00 |
| 2015-05-30T11:00:00 | 2015-05-30T11:45:00 |
+---------------------+---------------------+
27 rows in set (0.00 sec)
这是我最近的尝试(经过许多其他尝试):
mysql> select * from (select *, IF((slotStart<apptStart and slotEnd<apptStart) or (slotStart>apptEnd and slotEnd>apptEnd),1,0) as exclude from (select allSlots.startTime as slotStart, allSlots.endTime as slotEnd, existingAppts.startTime as apptStart, existingAppts.endTime as apptEnd from allSlots left join existingAppts on date(allSlots.startTime)=date(existingAppts.startTime) order by allSlots.startTime) as A group by slotStart, exclude desc) as B where exclude=0 group by slotStart;
+---------------------+---------------------+---------------------+---------------------+---------+
| slotStart | slotEnd | apptStart | apptEnd | exclude |
+---------------------+---------------------+---------------------+---------------------+---------+
| 2015-05-28T09:45:00 | 2015-05-28T10:30:00 | 2015-05-28T10:30:00 | 2015-05-28T12:15:00 | 0 |
| 2015-05-28T10:00:00 | 2015-05-28T10:45:00 | 2015-05-28T10:30:00 | 2015-05-28T12:15:00 | 0 |
| 2015-05-28T10:15:00 | 2015-05-28T11:00:00 | 2015-05-28T10:30:00 | 2015-05-28T12:15:00 | 0 |
| 2015-05-28T10:30:00 | 2015-05-28T11:15:00 | 2015-05-28T10:30:00 | 2015-05-28T12:15:00 | 0 |
| 2015-05-28T10:45:00 | 2015-05-28T11:30:00 | 2015-05-28T10:30:00 | 2015-05-28T12:15:00 | 0 |
| 2015-05-28T11:00:00 | 2015-05-28T11:45:00 | 2015-05-28T10:30:00 | 2015-05-28T12:15:00 | 0 |
| 2015-05-29T09:30:00 | 2015-05-29T10:15:00 | 2015-05-29T10:15:00 | 2015-05-29T10:45:00 | 0 |
| 2015-05-29T09:45:00 | 2015-05-29T10:30:00 | 2015-05-29T10:15:00 | 2015-05-29T10:45:00 | 0 |
| 2015-05-29T10:00:00 | 2015-05-29T10:45:00 | 2015-05-29T10:15:00 | 2015-05-29T10:45:00 | 0 |
| 2015-05-29T10:15:00 | 2015-05-29T11:00:00 | 2015-05-29T10:15:00 | 2015-05-29T10:45:00 | 0 |
| 2015-05-29T10:30:00 | 2015-05-29T11:15:00 | 2015-05-29T11:00:00 | 2015-05-29T11:45:00 | 0 |
| 2015-05-29T10:45:00 | 2015-05-29T11:30:00 | 2015-05-29T11:00:00 | 2015-05-29T11:45:00 | 0 |
| 2015-05-29T11:00:00 | 2015-05-29T11:45:00 | 2015-05-29T11:00:00 | 2015-05-29T11:45:00 | 0 |
| 2015-05-30T09:00:00 | 2015-05-30T09:45:00 | NULL | NULL | 0 |
| 2015-05-30T09:15:00 | 2015-05-30T10:00:00 | NULL | NULL | 0 |
| 2015-05-30T09:30:00 | 2015-05-30T10:15:00 | NULL | NULL | 0 |
| 2015-05-30T09:45:00 | 2015-05-30T10:30:00 | NULL | NULL | 0 |
| 2015-05-30T10:00:00 | 2015-05-30T10:45:00 | NULL | NULL | 0 |
| 2015-05-30T10:15:00 | 2015-05-30T11:00:00 | NULL | NULL | 0 |
| 2015-05-30T10:30:00 | 2015-05-30T11:15:00 | NULL | NULL | 0 |
| 2015-05-30T10:45:00 | 2015-05-30T11:30:00 | NULL | NULL | 0 |
| 2015-05-30T11:00:00 | 2015-05-30T11:45:00 | NULL | NULL | 0 |
+---------------------+---------------------+---------------------+---------------------+---------+
22 rows in set (0.00 sec)
您可以看到包含5/29的多个时间段,这些时间段不应与该日期的现有事件冲突。
这对查询是否可行,或者它是否需要结果集上的应用程序逻辑?
答案 0 :(得分:1)
我想我拥有它。这似乎有效。如果我错了,请纠正我。
select t1.startTime,t1.endTime,t2.endTime as appt from allSlots t1 left join existingAppts t2 on ((t1.startTime >= t2.startTime and t1.startTime < t2.endTime) or (t1.endTime > t2.startTime and t1.endTime <= t2.endTime)) where t2.endTime IS NULL order by t1.startTime;
+---------------------+---------------------+------+
| startTime | endTime | appt |
+---------------------+---------------------+------+
| 2015-05-28T09:00:00 | 2015-05-28T09:45:00 | NULL |
| 2015-05-28T09:15:00 | 2015-05-28T10:00:00 | NULL |
| 2015-05-28T09:30:00 | 2015-05-28T10:15:00 | NULL |
| 2015-05-28T09:45:00 | 2015-05-28T10:30:00 | NULL |
| 2015-05-29T09:00:00 | 2015-05-29T09:45:00 | NULL |
| 2015-05-29T09:15:00 | 2015-05-29T10:00:00 | NULL |
| 2015-05-29T09:30:00 | 2015-05-29T10:15:00 | NULL |
| 2015-05-30T09:00:00 | 2015-05-30T09:45:00 | NULL |
| 2015-05-30T09:15:00 | 2015-05-30T10:00:00 | NULL |
| 2015-05-30T09:30:00 | 2015-05-30T10:15:00 | NULL |
| 2015-05-30T09:45:00 | 2015-05-30T10:30:00 | NULL |
| 2015-05-30T10:00:00 | 2015-05-30T10:45:00 | NULL |
| 2015-05-30T10:15:00 | 2015-05-30T11:00:00 | NULL |
| 2015-05-30T10:30:00 | 2015-05-30T11:15:00 | NULL |
| 2015-05-30T10:45:00 | 2015-05-30T11:30:00 | NULL |
| 2015-05-30T11:00:00 | 2015-05-30T11:45:00 | NULL |
+---------------------+---------------------+------+
16 rows in set (0.00 sec)