“PostgreSQL中OVERLAPS函数的陷阱”
在PostgreSQL中,有一个方便的运算符称为OVERLAPS,用于判断两个时间间隔是否重叠。
3月1日至3月31日之间
- 3/30~3/31は重なる?
SELECT (DATE '2016-03-01', DATE '2016-03-31') OVERLAPS
(DATE '2016-03-30', DATE '2016-03-31')
=> true
嗯嗯。
- 3/30は重なる?
SELECT (DATE '2016-03-01', DATE '2016-03-31') OVERLAPS
(DATE '2016-03-30', DATE '2016-03-30')
=> true
嗯嗯。
- 3/1は重なる?
SELECT (DATE '2016-03-01', DATE '2016-03-31') OVERLAPS
(DATE '2016-03-01', DATE '2016-03-01')
=> true
嗯嗯。
- 3/31は重なる?
SELECT (DATE '2016-03-01', DATE '2016-03-31') OVERLAPS
(DATE '2016-03-31', DATE '2016-03-31')
=> false
嗯?
看起来,如果(从,到)的日期相同,那么判断它们不会重叠,就好像它们在另一端一样。
解决方法 fǎ)
使用范围型的daterange,可以正确地判断。
SELECT daterange(DATE '2016-03-01', DATE '2016-03-31', '[]') &&
daterange(DATE '2016-03-31', DATE '2016-03-31', '[]')
=> true
最后的'[]’表示开始和结束点都是闭区间。
另外,如果是范围类型的话,也可以获取共同部分。
SELECT daterange(DATE '2016-03-01', DATE '2016-03-31', '[]') *
daterange(DATE '2016-03-31', DATE '2016-03-31', '[]')
=> [2016-03-31,2016-04-01)
最后的’)’ 表示它是一个开区间。
使用区间范围型的注意事项。
表示没有共同部分的方式不是null或”,而是empty。
SELECT daterange(DATE '2016-03-01', DATE '2016-03-31', '[]') *
daterange(DATE '2016-04-01', DATE '2016-04-02', '[]') = 'empty'
=> true
在这种情况下,empty是指daterange类型的空值。
还提供了一个名为isempty()的函数。
SELECT isempty(daterange(DATE '2016-03-01', DATE '2016-03-31', '[]') *
daterange(DATE '2016-04-01', DATE '2016-04-02', '[]'))
=> true