Mysql查询以确定日期时间间隔中是否包含给定的日期时间

时间:2017-03-15 05:36:07

标签: php mysql datetime

如果给定的日期时间介于开始日期和结束日期之间,我就会坚持这个任务。 例如,这是一个日历数据表:

| id |  start               | end

| 31 | 2017-03-15 05:21:30  | 2017-03-15 06:21:30 
| 32 | 2017-03-14 06:25:30  | 2017-03-14 06:25:30 
| 33 | 2017-03-14 06:25:45  | 2017-03-14 06:25:45 

我必须使用以下开始和结束日期时间将新数据插入表中:

start: 2017-03-15 05:30:30 end: 2017-03-15 06:30:30

但在此之前,我必须检查表格中任何日期时间间隔内是否存在开始日期和结束日期。

结果应该是不会插入给定的开始日期和结束日期,因为它会下降或者包含在表格id 31日期时间间隔之间。

我应该如何使用查询来做到这一点?我尝试过这种查询:Select * from calendar_date as c where c.start >= start AND c.end <= end 确定给定的开始和结束日期时间存在但没有找到结果,我想我搞砸了查询。我真的希望有人可以帮我查一下。

2 个答案:

答案 0 :(得分:1)

你走了:

Select * from calendar_date as ,c where LEAST(c.end, end) - GREATEST(c.start, start) > 0

答案 1 :(得分:0)

如果您正在检查时间范围是否与另一个重叠,则诀窍是检查是否存在具有以下条件的行:

@end > t1.start
AND
@start < t1.end

此处@start@end代表时间窗口的起点和终点,与表格进行比较。

每次看到它都会带来精神上的痛苦,因为它非常简单。

如果在现有窗口开始之前开始之后,有问题的时间窗口结束,那么必然会有重叠。

在导致上述表达式为false的条件中找到逻辑证明 - 如果任一比较计算结果为false,则组合表达式为false:

如果在建立的窗口开始后新窗口没有结束,那么它必须在建立的窗口开始之前结束,因此不会重叠。 (条件1,@end > t1.start)。

如果新窗口在建立的窗口结束之前没有开始,那么它必须在建立的窗口结束后开始,因此不会重叠(条件2,@start < t1.end)。

如上所述,此查询与精确触摸的窗口不匹配 - 允许从正好在另一个窗口的末尾开始或在另一个窗口的开头完全结束的窗口。如果您不想这样做,请使用>=<=

要阻止插入,您需要BEFORE INSERT触发器。

DELIMITER $$
DROP TRIGGER IF EXISTS calendar_date_bi $$
CREATE TRIGGER calendar_date_bi
  BEFORE INSERT ON calendar_date
  FOR EACH ROW
BEGIN

  IF EXISTS(SELECT * FROM calendar_date cd
             WHERE NEW.end > cd.start AND NEW.start < cd.end) THEN
    SIGNAL SQLSTATE '45000'
       SET MESSAGE_TEXT = 'overlapping date ranges are not allowed';
  END IF;

END $$
DELIMITER ;