【问题标题】:Mysql query to determine if the given datetime is included in the datetime intervalMysql查询确定给定的日期时间是否包含在日期时间间隔中
【发布时间】:2017-03-15 05:36:07
【问题描述】:

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

| 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 确定给定的开始和结束日期时间存在但没有找到结果,我想我搞砸了查询。我真的希望有人可以帮我检查一下。

【问题讨论】:

    标签: php mysql datetime


    【解决方案1】:

    给你:

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

    【讨论】:

    • 这不是插入,而是选择。
    • @TimBiegeleisen:你能解释一下吗?
    • @dotNet,我已经为我的查询手动添加了开始和结束日期时间:select * from calendar_item as c where TIMESTAMPDIFF(SECOND, LEAST(c.end, "2017-03-15 06:30:30") - GREATEST(c.start, "2017-03-15 05:30:30")) > 0;,但我提示我的语法有错误。顺便谢谢你的回答。
    • @dotNET,你是个好人!有用!是的,是的,我会转换它。
    • @G.Curs:很高兴它有帮助。如果您使用标准 MySQL 格式之一,例如'YYYY-MM-DD HH:MM:SS',则无需转换。
    【解决方案2】:

    如果您要检查一个时间范围是否与另一个时间范围完全重叠,诀窍是检查是否存在满足以下条件的行:

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

    这里@start@end 代表我要与表格进行比较的时间窗口的开始和结束。

    每当我看到它时,我都会感到很痛苦,因为它非常简单。

    如果有问题的时间窗口在现有窗口开始之后结束并且在现有窗口结束之前开始,则必然存在重叠。

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

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

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

    正如所写,这个查询不匹配精确接触的窗口——一个窗口正好开始于另一个窗口的结尾或正好结束于另一个窗口的开头——是允许的。如果你不想这样,也可以使用&gt;=&lt;=

    要阻止插入,您需要一个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 ;
    

    【讨论】:

      猜你喜欢
      • 2018-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-08
      • 2012-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多