2014-09-02 111 views
0

这是例子之间取结果:Postgres的查询到两个日期

create table test (
id int, 
name varchar(6), 
start_date date, 
end_date date 
); 


insert into test (id,name, start_date, end_date) values (1,'aaa', '2014-07-01', '2014-07-30'); 
insert into test (id,name, start_date, end_date) values (2,'bbb', '2014-07-01', '2014-08-30'); 
insert into test (id,name, start_date, end_date) values (3,'ccc', '2014-08-01', '2014-08-30'); 
insert into test (id,name, start_date, end_date) values (4,'ddd', '2014-08-16', '2014-08-30'); 
insert into test (id,name, start_date) values (5,'eee', '2014-07-01'); 
insert into test (id,name, start_date) values (6,'fff', '2014-08-16'); 

我需要写的查询,其中的结果将是:

2;"bbb";"2014-07-01";"2014-08-30" 
3;"ccc";"2014-08-01";"2014-08-30" 
4;"ddd";"2014-08-16";"2014-08-30" 
5;"eee";"2014-07-01";"" 
6;"fff";"2014-08-16";"" 

我写这样的:

select * from test 
where (start_date >= '2014-08-15' and (end_date <= current_Date or end_date is null)) or 
(start_date <= '2014-08-15' and end_date is null) ; 

但我只看到ddd,eee和fff记录。

+0

什么办法?您的WHERE子句按设计工作。 – 2014-09-02 19:01:29

回答

1

我在(智慧地)猜测你想要与2014-08-15重叠的任何时期到当前日期。如果是这样,这个逻辑返回你想要的:

select * 
from test 
where (start_date >= '2014-08-15' and (end_date <= current_Date or end_date is null)) or 
     (start_date <= '2014-08-15' and (end_date > '2014-08-15' or end_date is null)); 

Here是一个SQL小提琴。

+0

确实^^你是我的英雄!非常感谢! – Rawness 2014-09-02 19:15:53

2

而不是比较运算符,你可以实际使用PostgreSQL自己检测日期(&时间)的重叠。实际上有2层结构:

1)的SQL兼容OVERLAPS operator

(start1, end1) OVERLAPS (start2, end2)
(start1, length1) OVERLAPS (start2, length2)

这一次没有处理好一个开放式日期的时期,但您可以使用该日期的特殊infinity日期。

select * 
from test 
where (date '2014-08-15', current_date) overlaps 
     (start_date, coalesce(end_date, date 'infinity')); 

据我所知,你不能使用任何索引上面加快查询。

另外:

每个时间段被认为是代表了半开区间开始 < = 时间 < ,除非开始和结束是相等的在这种情况下它表示单时间瞬间。

2)使用daterange type

范围可以是无限的,你可以明确设置如何处理域范围(包括与否)。

select * 
from test 
where daterange(start_date, end_date, '[]') && 
     daterange(date '2014-08-15', current_date, '[]'); 

此外,您还可以加快这个查询,通过在daterange表达应用gist指数:

create index on test using gist ((daterange(start_date, end_date, '[]'))); 

SQLFiddle