2014-09-02 108 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