检查两个日期间隔是否相交

时间:2013-09-08 11:47:46

标签: mysql sql select

我需要检查MySQL以查看两个日期间隔是否相交。 为了更好地解释我的问题:我有一个事件管理模块。如果我们有一个像这样添加的事件:

  

开始日期:'2013-09-09 08:00:00'

     

结束日期:'2013-09-09 10:00:00'

现在我想添加另一个类似的事件:

案例A:

  

开始日期:'2013-09-09 09:00:00'

     

结束日期:'2013-09-09 11:00:00'

或者像这样:

案例B:

  

开始日期:'2013-09-09 07:00:00'

     

结束日期:'2013-09-09 12:00:00'

我不应该这样做,因为在该时间间隔(08-10)中已经添加了一个事件

对于第一个例子(case A),我通过这样做解决了这个问题:

SELECT * FROM `events` as e 
    where 
    '2013-09-09 08:00:00' between e.ev_date_start and e.ev_date_end -- date start
    OR
    '2013-09-09 11:00:00' between e.ev_date_start and e.ev_date_end -- date end

但对于第二种情况(case B),我无法搞清楚......

5 个答案:

答案 0 :(得分:6)

仅测试已分配时间块的开始时间或待分配时间块的开始时间不会相互之间。

select * from `events` as e 
where '2013-09-09 08:00:00' between e.ev_date_start and e.ev_date_end
or e.ev_date_start between '2013-09-09 08:00:00'and '2013-09-09 11:00:00'

答案 1 :(得分:4)

想法是检查它们是否相交,然后否定。

NOT ('2013-09-09 08:00:00' >= e.ev_date_end OR e.ev_date_start >= '2013-09-09 11:00:00')

在逻辑上等同于

'2013-09-09 08:00:00' < e.ev_date_end AND e.ev_date_start < '2013-09-09 11:00:00'

答案 2 :(得分:2)

要覆盖它们,您需要在WHERE子句中使用4个语句:

select *
  from `events` as e 
 where '2013-09-09 07:00:00' between e.ev_date_start and e.ev_date_end
    or '2013-09-09 12:00:00' between e.ev_date_start and e.ev_date_end
    or e.ev_date_start between '2013-09-09 07:00:00' and '2013-09-09 12:00:00'
    or e.ev_date_end between '2013-09-09 07:00:00' and '2013-09-09 12:00:00'

看起来可能更简单:

select *
  from `events` as e 
 where @start between e.ev_date_start and e.ev_date_end
    or @end between e.ev_date_start and e.ev_date_end
    or e.ev_date_start between @start and @end
    or e.ev_date_end between @start and @end

答案 3 :(得分:0)

一个小例子:

我想找出这两个mysql日期是否与数据库中的日期相交;

'2015-02-01 00:00:00', '2015-02-28 23:59:59'

要在phpMyAdmin或MySQL Workbench上执行的查询;

CREATE TEMPORARY TABLE `date_temp`
(
  `id` int(5) NOT NULL AUTO_INCREMENT,
  `date_1` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'Start date',
  `date_2` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT 'Expiration date',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

INSERT INTO `date_temp` (`date_1`, `date_2`)
VALUES 
('2015-01-01 00:00:00', '2015-01-30 23:59:59'),
('2015-02-02 00:00:00', '2015-02-27 23:59:59'),
('2015-03-02 00:00:00', '2015-03-31 23:59:59'),
('2015-01-15 00:00:00', '2015-03-15 23:59:59'),
('2015-01-15 00:00:00', '2015-02-15 23:59:59'),
('2015-02-15 00:00:00', '2015-03-15 23:59:59');

SELECT * 
FROM `date_temp`
WHERE 
NOT 
(
    ('2015-02-01 00:00:00' > `date_2`) OR 
    (`date_1` > '2015-02-28 23:59:59') OR 
    (`date_2` < `date_1`) OR 
    ('2015-02-28 23:59:59' < '2015-02-01 00:00:00')
);

DROP TABLE `date_temp`;

查询创建一个表,插入一些数据并测试两个日期是否与表中存在的日期相交。然后清理桌子。

答案 4 :(得分:0)

请注意,您预先保证(通过一些UI验证) 2013-09-09 12:00:00 大于 2013-09-09 07:00: 00 你可以这样简单地通过检查:

WHERE 1
AND '2013-09-09 07:00:00' <= e.ev_date_end 
AND '2013-09-09 12:00:00' >= e.ev_date_start

此检查更简单,更快捷。无需搞乱OR语句或其他复杂的逻辑。始终要记住,OR会严重损害SQL中的性能。