测试两个日期的间隔是否不参与其他间隔

时间:2016-10-25 19:56:46

标签: sql postgresql

我的表格StartDateEndDate就像这样:

+----+----------------------+--------------------+
| id | start_date           | end_date           |
+----+----------------------+--------------------+
| 1  | 2016-10-24 09:00:00  |2016-10-24 10:30:00 |
| 2  | 2016-10-31 09:00:00  |2016-10-31 10:30:00 |
+----+----------------------+--------------------+

我想测试我的新记录(new start_dateend_date是否不参与其他记录的ONE SECONDE

我曾经测试过所有可能性,但我认为这需要很长时间才能解决这个问题,我尝试使用这个查询它工作正常,但需要时间:

select * from myTable where 

(new_start_date >= myTable.start_date and new_end_date <= myTable.end_date) 

or (new_start_date > myTable.start_date and new_end_date < myTable.end_date) 

or (new_start_date > myTable.start_date and new_end_date < myTable.end_date) 

or (new_start_date < myTable.start_date and new_end_date > myTable.end_date) 

or (new_start_date < myTable.start_date and new_end_date = myTable.end_date) 

or (new_start_date = myTable.start_date and new_end_date > myTable.end_date)

这个问题还有其他解决办法吗?

以下是我可以获得的所有可能性

如果:

newSD_______startdate___newED_____enddate_____ : return false

newSD_______startdate________enddate___newED__ : return false

___startdate___newSD____newED_____enddate_____ : return false

___startdate___newSD_____enddate___newED______ : return false

____startdate_____enddate___newED___newED_________ : return true

___newED___newED___startdate_____enddate__________ : return true

谢谢。

2 个答案:

答案 0 :(得分:3)

这将显示与新的开始/结束间隔重叠的所有行。

select *
from myTable 
where (new_start_date, new_end_date) overlaps (start_date, end_date);

以上是ANSI标准SQL。

如果需要,可以创建一个阻止插入重叠行的约束。

这是通过exclusion constraint超过range type完成的 - 这是一种唯一约束,但适用于范围。

alter table mytable
  add constraint no_overlap
  exclude using gist (tsrange(start_date, end_date) with &&);

排除限制是Postgres特定的。

答案 1 :(得分:2)

这太复杂了。看看所有的可能性:如果&#34; x&#34;和&#34; y&#34;是您需要测试的值,&#34; a&#34;和&#34; b&#34;是您的数据库值,然后是这里的所有内容:

           a   b
1      x y           - x<a & y<a   - no overlap
2      x   y         - x<a & y=a
3      x     y       - x<a & a <= y <= b
4      x       y     - x<a & y=b
5      x         Y   - x<a & y>b   - complete overlap
6          x y       - x=a & y<b
7          x   y     - x=a & y=b   - same dates
8          x     y   - x=a & y>b
9            xy      - (x>a & x<b) & (y>a & y<b) - complete overlap
10             x y     - (x>a & x<b) & b=y
11             x y   - x=b & y>b
12               x y - x>a & y>a   - no overlap

在所有这些中,你只关心112 - 完全没有重叠,这意味着你的逻辑陈述只是

if ((y < a) || (x > b)) {
    ... no overlap
}