这是对我之前提问A query for finding the nearest free time slot in mysql - why it doesn't work?
的跟进基本上我有一张桌子:
id | start_time | duration
1 | 2015-10-21 19:41:35 | 15
2 | 2015-10-21 19:41:50 | 15
3 | 2015-10-21 19:42:05 | 15
4 | 2015-10-21 19:42:35 | 15
etc.
它包含事件start_time及其持续时间。我请求帮助找到可以在现有事件之间放置事件的最近时间段。 @Richard提出了一个完美的答案https://stackoverflow.com/a/33689786/3766930并提出了一个问题:
SELECT (a.start_time + INTERVAL a.duration SECOND) AS free_after FROM notes a
WHERE
NOT EXISTS ( SELECT 1 FROM notes b WHERE b.start_time
BETWEEN (a.start_time + INTERVAL a.duration SECOND) AND
(a.start_time + INTERVAL a.duration SECOND) + INTERVAL 15 SECOND - INTERVAL 1 MICROSECOND) AND
(a.start_time + INTERVAL a.duration SECOND) BETWEEN '2015-10-21 19:41:30' AND '2015-10-21 19:43:50'
效果很好。
现在我想知道是否有可能在现有日期之间找到最合适的日期,而且也就在它们之前。
例如:我将begin_date设置为2015-10-21 16:00:00
,将end_date设置为2015-10-21 21:00:00
。目前,@ Richard的查询结果为2015-10-21 19:42:20
。但有没有办法创建一个查询,在这个结果中,2015-10-21 19:41:20
将返回到已经在数据库中的第一个日期最近的查询?
答案 0 :(得分:4)
一个简单的解决方案是使用date_sub和order by语句,将结果限制为仅显示1条记录。
结果如下:
SELECT date_sub(start_time, interval duration second) as free_before FROM `notes` where start_time>'2015-10-21 16:00:00' order by start_time asc limit 1
为您加分
使用@Richard提供的上一个解决方案。将所有这些放在一起以显示1个表中的所有空闲时间可能会产生以下结果:
select * from (SELECT date_sub(start_time, interval duration second) as free_times FROM `notes` where start_time>'2015-10-21 16:00:00' order by start_time asc limit 1) a
union
(SELECT (a.start_time + INTERVAL a.duration SECOND) AS free_times FROM notes a
WHERE
NOT EXISTS ( SELECT 1 FROM notes b WHERE b.start_time
BETWEEN (a.start_time + INTERVAL a.duration SECOND) AND
(a.start_time + INTERVAL a.duration SECOND) + INTERVAL 15 SECOND - INTERVAL 1 MICROSECOND) AND
(a.start_time + INTERVAL a.duration SECOND) BETWEEN '2015-10-21 19:41:30' AND '2015-10-21 19:43:50')
修改强>
我只会写我的部分查询。另一部分工作正常,只有你想让我改变它我会(永远不会修复没有破坏的东西)
如果你想要10秒的间隔 - > <>
SELECT date_sub(start_time, interval 10 second) as free_times FROM `notes` where start_time>'2015-10-21 16:00:00' order by start_time asc limit 1
如果您想要15秒的间隔 - > <>
SELECT date_sub(start_time, interval 15 second) as free_times FROM `notes` where start_time>'2015-10-21 16:00:00' order by start_time asc limit 1
在这种情况下,您必须相应地更改start_time和持续时间。
答案 1 :(得分:1)
这对你有用吗?
假设:
select * from notes;
+----+---------------------+----------+
| id | start_time | duration |
+----+---------------------+----------+
| 1 | 2015-11-17 10:10:10 | 15 |
| 2 | 2015-11-17 10:20:40 | 15 |
| 3 | 2015-11-17 10:30:00 | 15 |
+----+---------------------+----------+
结果:
select (start_time - interval 15 second) as earlier_date
from notes
where start_time > '2015-11-17 10:15:00'
AND start_time < '2015-11-17 10:25:00'
order by start_time
limit 1;
+---------------------+
| earlier_date |
+---------------------+
| 2015-11-17 10:20:25 |
+---------------------+
重要提示:此示例并未注意可能会立即落在搜索窗口前的条目(因为您的示例并未包含任何内容)。如果在搜索窗口之前存在冲突条目,则此查询按将创建重叠。
答案 2 :(得分:-2)
拿你的基表并插入一个假行,这是一个最小的开始时间并减去15秒。
所以不用注释,而是使用这样的子查询:
SELECT
MIN(start_time) - INTERVAL 15 seconds AS start_time,
0 AS duration
FROM notes
UNION ALL
SELECT start_time, duration
FROM notes