猿问

比较日期范围


在MySQL中,如果我有一个日期范围列表(范围-开始和范围-结束)。G.


10/06/1983 to 14/06/1983

15/07/1983 to 16/07/1983

18/07/1983 to 18/07/1983

我想检查另一个日期范围是否包含列表中的任何一个范围,我将如何做到这一点?


G.


06/06/1983 to 18/06/1983 = IN LIST

10/06/1983 to 11/06/1983 = IN LIST

14/07/1983 to 14/07/1983 = NOT IN LIST


慕的地10843
浏览 602回答 3
3回答

神不在的星期二

这是一个经典的问题,如果你逆转逻辑,它实际上会更容易。让我举个例子。我将在这里张贴一段时间,以及所有其他时期的不同变化,以某种方式重叠。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|-------------------|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;compare&nbsp;to&nbsp;this&nbsp;one &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|---------|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contained&nbsp;within &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|----------|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contained&nbsp;within,&nbsp;equal&nbsp;start &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|-----------|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contained&nbsp;within,&nbsp;equal&nbsp;end &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|-------------------|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contained&nbsp;within,&nbsp;equal&nbsp;start+end &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|------------|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;not&nbsp;fully&nbsp;contained,&nbsp;overlaps&nbsp;start &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|---------------|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;not&nbsp;fully&nbsp;contained,&nbsp;overlaps&nbsp;end &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|-------------------------|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;overlaps&nbsp;start,&nbsp;bigger &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|-----------------------|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;overlaps&nbsp;end,&nbsp;bigger &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|------------------------------|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;overlaps&nbsp;entire&nbsp;period另一方面,让我发布所有不重叠的内容:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|-------------------|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;compare&nbsp;to&nbsp;this&nbsp;one &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|---|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ends&nbsp;before &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|---|&nbsp;&nbsp;&nbsp;&nbsp;starts&nbsp;after因此,如果简单地将比较简化为:starts&nbsp;after&nbsp;end ends&nbsp;before&nbsp;start然后你会找到所有不重叠的,然后你会找到所有不匹配的周期。对于最后一个不是在列表中的例子,您可以看到它与这两个规则相匹配。您需要确定下列期间是否在您的范围内或范围之外:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|-------------| &nbsp;&nbsp;&nbsp;|-------|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;equal&nbsp;end&nbsp;with&nbsp;start&nbsp;of&nbsp;comparison&nbsp;period &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|-----|&nbsp;&nbsp;&nbsp;equal&nbsp;start&nbsp;with&nbsp;end&nbsp;of&nbsp;comparison&nbsp;period如果表中有名为range_end和range_start的列,下面提供一些简单的SQL来检索所有匹配的行:SELECT&nbsp;*FROM&nbsp;periodsWHERE&nbsp;NOT&nbsp;(range_start&nbsp;>&nbsp;@check_period_end&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OR&nbsp;range_end&nbsp;<&nbsp;@check_period_start)注意不在里面。因为这两个简单的规则可以找到所有的非匹配行,一个简单的不一定会倒过来说:如果它不是不匹配的行之一,则必须是匹配的行之一。.在这里应用简单的反转逻辑来消除NOT,您将得到以下结果:SELECT&nbsp;*FROM&nbsp;periodsWHERE&nbsp;range_start&nbsp;<=&nbsp;@check_period_end&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AND&nbsp;range_end&nbsp;>=&nbsp;@check_period_start

绝地无双

以您的示例范围为06/06/1983至18/06/1983,并假设您的列名为启动和端部对于您的范围,您可以使用这样的子句where&nbsp;('1983-06-06'&nbsp;<=&nbsp;end)&nbsp;and&nbsp;('1983-06-18'&nbsp;>=&nbsp;start)例如,检查测试范围的开始在数据库范围结束之前,测试范围的结束在数据库范围开始后或开始时。

MM们

我创建了函数来处理MySQL中的这个问题。只需将日期转换为使用前的秒。DELIMITER&nbsp;;;CREATE&nbsp;FUNCTION&nbsp;overlap_interval(x&nbsp;INT,y&nbsp;INT,a&nbsp;INT,b&nbsp;INT)RETURNS&nbsp;INTEGER&nbsp;DETERMINISTICBEGINDECLARE &nbsp;&nbsp;&nbsp;&nbsp;overlap_amount&nbsp;INTEGER; &nbsp;&nbsp;&nbsp;&nbsp;IF&nbsp;(((x&nbsp;<=&nbsp;a)&nbsp;AND&nbsp;(a&nbsp;<&nbsp;y))&nbsp;OR&nbsp;((x&nbsp;<&nbsp;b)&nbsp;AND&nbsp;(b&nbsp;<=&nbsp;y))&nbsp;OR&nbsp;(a&nbsp;<&nbsp;x&nbsp;AND&nbsp;y&nbsp;<&nbsp;b))&nbsp;THEN &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IF&nbsp;(x&nbsp;<&nbsp;a)&nbsp;THEN &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IF&nbsp;(y&nbsp;<&nbsp;b)&nbsp;THEN &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SET&nbsp;overlap_amount&nbsp;=&nbsp;y&nbsp;-&nbsp;a; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ELSE &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SET&nbsp;overlap_amount&nbsp;=&nbsp;b&nbsp;-&nbsp;a; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;END&nbsp;IF; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ELSE &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IF&nbsp;(y&nbsp;<&nbsp;b)&nbsp;THEN &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SET&nbsp;overlap_amount&nbsp;=&nbsp;y&nbsp;-&nbsp;x; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ELSE &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SET&nbsp;overlap_amount&nbsp;=&nbsp;b&nbsp;-&nbsp;x; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;END&nbsp;IF; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;END&nbsp;IF; &nbsp;&nbsp;&nbsp;&nbsp;ELSE &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SET&nbsp;overlap_amount&nbsp;=&nbsp;0; &nbsp;&nbsp;&nbsp;&nbsp;END&nbsp;IF; &nbsp;&nbsp;&nbsp;&nbsp;RETURN&nbsp;overlap_amount;END&nbsp;;;DELIMITER&nbsp;;
随时随地看视频慕课网APP
我要回答