2011-06-09 150 views
0

我有一個PostgreSQL數據庫的事件。每個事件都有一個日期時間或間隔。公用數據存儲在events表中,日期存儲在events_datesdatetime字段)或events_intervalsstarts_date,ends_date均爲date字段)中。按日/月/年/日/月/日/年等搜索SQL查詢

樣品的日期時間事件

  • 我出生於1930年6月9日
  • 我得到了我的駕駛在1950年7月12日
  • 聖誕節許可證是1900年12月24日(1900對於每年reoccuring事件預留)

樣品間隔事件

  • 我會在2011-06-09到2011-07-23之間度假

現在我有一個用戶希望查找這些事件。他們將能夠填寫表格fromto字段,並且在這些字段中,他們可以在一個或兩個字段中輸入完整日期,日,月,年,日和月,日,年,月和年。

示例查詢

  • 從5月3日至2012年12月21日將尋找5月3日和12月21日,其最高年份是2012
  • 從第3天至15日:尋找第三之間的事件之間的事件和每一個月份和年份
  • 從第3天的第15天將尋找事件的每一個年份和月份的第3天(相同的,如果from是空的,to不是)
  • 從5月3日至6月份將尋找事件5月3日至最後一天每年的六月Y的

如何編寫一個查詢maintanable任何提示(但並不一定要快)?

,我們認爲

  • 寫所有可能fromto和日/月/年組合有些東西 - 不maintable
  • 例如比較日期爲字符串輸入:____-06-__其中_是一個通配符 - 我就不會產生所有可能的組合,但是,這並不爲間隔

回答

1

您可以編寫可維護的查詢另外是快速通過使用PG /時間延長工作:

https://github.com/jeff-davis/PostgreSQL-Temporal

create index on events using gist(period(start_date, end_date)); 

select * 
from events 
where period(start_date, end_date) @> :date; 

select * 
from events 
where period(start_date, end_date) && period(:start, :end); 

你甚至可以用它來禁止重疊表約束:

alter table events 
add constraint overlap_excl 
exclude using gist(period(start_date, end_date) WITH &&); 

寫的所有可能的,並日/月/年組合 - 不maintable

它其實更容易維護比你想象的,如:

select * 
from events 
join generate_series(:start_date, :end_date, :interval) as datetime 
on start_date <= datetime and datetime < end_date; 

但它的更好地使用上述期間類型。