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

Mysql 检查两个日期间隔是否相交,mysql,sql,select,Mysql,Sql,Select,我需要在MySQL中检查两个日期间隔是否相交。 为了更好地解释我的问题:我有一个事件管理模块。如果我们有这样添加的事件: 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

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

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
开始日期:
'2013-09-09 08:00:00'

结束日期:
'2013-09-09 10: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
案例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)中已经添加了一个事件

对于第一个示例(
案例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

但是对于第二种情况(
情况B
),我很难弄清楚……

为了涵盖这两种情况,在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

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

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'
'2013-09-09 08:00:00'
仅测试已分配的时间块或待分配的时间块的开始时间不在彼此之间

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'
举个小例子:

我想知道这两个mysql日期是否与数据库上的日期相交

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

要在phpMyAdmin或MySQL工作台上执行的查询

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`;
创建临时表'date\u temp`
(
`id`int(5)非空自动增量,
`date_1 `日期时间不为空默认值'0000-00-00 00:00:00'注释'开始日期',
`date_2 `日期时间不为空默认值'0000-00-00 00:00:00'注释'Expiration date',
主键(`id`)
)ENGINE=MyISAM默认字符集=utf8 COLLATE=utf8\U bin;
插入'date\u temp'('date\u 1','date\u 2`)
价值观
('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');
选择*
从“日期”开始`
哪里
不
(
('2015-02-01 00:00:00'>'date_2`)或
(`date_1`>'2015-02-28 23:59:59')或
(`date_2`<`date_1`)或
('2015-02-28 23:59:59' < '2015-02-01 00:00:00')
);
删除表'date\u temp';

该查询创建一个表,插入一些数据,并测试这两个日期是否与表中的日期相交。然后清除表格。

请记住,您预先保证(通过一些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
其中1
和“2013-09-09 07:00:00”=e.ev\u日期\u开始

这种检查更简单、更快。不需要弄乱逻辑或语句或其他复杂的逻辑。请始终记住,这可能会严重损害SQL的性能。

简单到
'2013-09-09 08:00:00'
这实际上是错误的。还有一个例子,让我们把日期命名为“A开始”,“B开始”,“AE”,“A结束”和“B结束”。可能的交叉组合是:AS-BS-AE-BE-BS-AS-AE-BE-AS-BS-BE-AE所以你需要:'AS'在'BS'和'BE'之间,或者'AE'在'BS'和'BE'之间,或者'BS'在'AS'和'AE'之间