Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何检查mysql中的两个日期范围是否重叠?_Mysql_Date - Fatal编程技术网

如何检查mysql中的两个日期范围是否重叠?

如何检查mysql中的两个日期范围是否重叠?,mysql,date,Mysql,Date,在mysql中,如何检查两个日期范围是否重叠 我有这个: 注意:我们有p.date\u开始我想你还有一个额外的测试。如果两个范围在一端重叠,或者如果第一个范围完全位于第二个范围内,则前两个语句将涵盖这两个范围 然后,您需要测试第二个范围是否完全包含在第一个范围内,其他任何内容都将在前两个测试中涵盖。为此,您只需要测试开始或结束 因此,我认为这是可行的 $query = "SELECT u.first_name, u.last_name, u.avatar_filename, p.id

在mysql中,如何检查两个日期范围是否重叠

我有这个:


注意:我们有
p.date\u开始我想你还有一个额外的测试。如果两个范围在一端重叠,或者如果第一个范围完全位于第二个范围内,则前两个语句将涵盖这两个范围

然后,您需要测试第二个范围是否完全包含在第一个范围内,其他任何内容都将在前两个测试中涵盖。为此,您只需要测试开始或结束

因此,我认为这是可行的

 $query = "SELECT u.first_name, u.last_name, u.avatar_filename, p.id, p.user_id, p.address, p.topic, p.latitude, p.longitude, d.name AS department_name
              FROM user u
              JOIN placement p ON p.user_id=u.id
              JOIN department d ON d.id = u.department_id
              WHERE p.active=1 AND (('{$dateA}' BETWEEN p.date_started AND p.date_finished) OR 
                                    ('{$dateB}' BETWEEN p.date_started AND p.date_finished) OR
                                    (p.date_started BETWEEN '{$dateA}' AND '{$dateB}'))";

如果我们保证
date\u start
datefinished
$DateA
$DateB
不为空,并且我们保证
date\u start
不大于
date\u finished

`s` represents `date_started`
`f` represents `date_finished`
`a` represents the smaller of `$DateA` and `$DateB`
`b` represents the larger of `$DateA` and `$DateB`
视觉上:

      s-----f       overlap
 -----+-----+-----  -------  
  a-b |     |        NO
  a---b     |        YES
  a-----b   |        YES
  a---------b        YES
  a-----------b      YES
      a---b |        YES
      a-----b        YES
      a-------b      YES
      | a-b |        YES
      | a---b        YES     
      | a-----b      YES     
      |     a-b      YES
      |     | a-b    NO
我们可以很容易地检测出没有“重叠”的范围:

( a > f OR b < s )
(a>f或b
当存在“重叠”时,我们可以很容易地否定这一点以返回“真”:

非(a>f或b
将其转换为SQL:

NOT ( GREATEST('{$dateA}','{$dateB}') < p.date_started
      OR LEAST('{$dateA}','{$dateB}') > p.date_finished
    )
NOT(最大({$dateA},{$dateB}')p.date_完成
)
检查重叠的逻辑
A->B
表示一个范围,
A->B
表示另一个范围

重叠场景1

AB
*----------*
ab
*----------*

重叠场景2

AB
*----------*
ab
*----------*

重叠场景3

AB
*----------*
ab
*---------------------*

重叠场景4-当a或b与a或b相同时

a == A || a == B || b == A || b == B  
通过检查DO 4,可以实现不同的场景 情景

(scenario 1 (+4) || scenario 2 (+4)  || scenario 3 )

(a >= A && a <= B) || (b >= A && b <= B) || (a < A && b > B)
我们的逻辑应该检查所有场景

(scenario 1 (+4) || scenario 2 (+4)  || scenario 3 )

(a >= A && a <= B) || (b >= A && b <= B) || (a < A && b > B)
(场景1(+4)|场景2(+4)|场景3)
(a>=a&&a=a&&b)

您可以覆盖所有日期重叠的情况,即使数据库中的“截止日期”可能为空,如下所示:

SELECT * FROM `tableName` t
WHERE t.`startDate` <= $toDate
AND (t.`endDate` IS NULL OR t.`endDate` >= $startDate);
从`tableName`t中选择*
其中t.`startDate`=$startDate);

无论如何,这将返回所有与新开始/结束日期重叠的记录。

如果您不知道A是在B之前还是之后,也不知道A-B是否可以完全嵌入开始/结束,或者反之亦然,那么我认为这是最简单的。嗯,时间是线性的,对吗?事件不能在开始之前结束!我没有说dateA和dateB是一个事件。它们只是两个可以任意顺序的日期。如果
magest
返回较晚的日期而
least
返回较早的日期,那么它不应该是
不应该是(magest({$dateA},{$dateB}')p.date u finished)
?@omega:是的,我是倒过来的。我已经编辑了我的答案。如果这四个值中的任何一个可以为空,则可能需要修改该条件来说明这一点。它还缩短了5个字节:-)当
date\u start
等于所检查范围的结束日期时,此答案也没有处理边缘情况。。。这是否是一种重叠?将
或p.date_finished作为NULL
条件插入SQL是有意义的,只要NULL值表示无限未来的一个点。在推荐SQL构造时,我们需要注意这一假设。因为并不是每个日期列中的每个空值都表示它。@DATE_finished的HusseinAkar空值是一个“缺失条件”,只有当空值表示一个覆盖整个未来的时段时,才需要修复它(如您的答案所示)。然后我们可以合并一个条件。但我们需要小心地收集空值行的特定含义。它还可以表示不能重叠的时段,或者可以表示一年或一小时的默认值。我没有深入研究处理所有边缘案件的细节。这个答案集中在被问到的问题上。
SELECT * FROM `tableName` t
WHERE t.`startDate` <= $toDate
AND (t.`endDate` IS NULL OR t.`endDate` >= $startDate);