2013-04-18 112 views
0

我正面臨着日曆的問題。選擇具有可重複日期時間的記錄PostgreSQL

我要提取所有記錄(事件)(通過選擇):1, 一個特定的日期,或 2.重複日期

的問題是正常的日曆顯示整個月(或特定的時間範圍),因此它是能夠選擇從一個子查詢生成的一個子集的記錄(和比較日期片段),即:

select (generate_series('2012-06-29 00:00:00', 
         '2012-07-03 00:00:00', 
         '5 minutes'::interval))::timestamp; 

我必須建立一個日曆的視圖類似的無限列表您可以向下滾動。所以我必須逐個顯示事件。當我選擇事件(即2012-06-29 00:00:00至2012-10-29 00:00:00)時,則聲明將不會考慮日期爲2012-10-30 00:00:00的記錄,這不是預期的。

如何選擇多個非連續日期?

數據庫模式:

CREATE TABLE "public"."events" (
"id" int4 DEFAULT nextval('events_id_seq'::regclass) NOT NULL, 
"date" timestamp(6), 
"date_repeat_interval" interval(6), 
"date_repeat_start" timestamp(6), 
"date_repeat_stop" timestamp(6), 
"event_name" varchar(255) NOT NULL 
) 
WITH (OIDS=FALSE); 

插入特定日期一些正規的事件:

INSERT INTO "public"."events" VALUES ('1', '2013-04-18 14:04:39', null, null, null, 'Regular 1'); 
INSERT INTO "public"."events" VALUES ('2', '2013-04-19 14:04:50', null, null, null, 'Regular 2'); 

而且從和日期插入帶間隔1和2天,並指定重複一些事件:

INSERT INTO "public"."events" VALUES ('3', null, '1 day', '2013-04-16 14:05:26', '2013-04-19 14:05:31', 'Repeatable 1'); 
INSERT INTO "public"."events" VALUES ('4', null, '2 days', '2013-04-17 14:05:49', '2013-06-15 14:05:53', 'Repeatable 2'); 

問題:

如何查詢數據庫有關範圍內的所有事件:從NOW到無限與極限10.它們按發生次序發生,包括可重複事件的多次發生。

+1

在它的當前形式您的問題沒有意義。爲什麼你會期望在你指定範圍之外的時間戳被考慮?你可以顯示錶的定義和你的SQL查詢?您可能需要製作一個sqlfiddle http://www.sqlfiddle.com – Eelke 2013-04-18 05:28:39

+0

什麼是可重複日期? – 2013-04-18 11:24:48

+0

當然,我會揭示這個話題。當我們在日曆中有可重複的事件時,我們希望不在範圍內:日,周,月,年(時間在特定範圍內),但我們希望將它們呈現爲可滾動列表(無限) ,每頁10個項目,就有問題,如何查詢數據庫來顯示這些事件。從現在到X,您無法關閉範圍,因爲在日期X + 1分鐘內可能會發生一個事件。我已經更新了這個問題並且包含了數據庫模式和簡要解釋的問題 – Athlan 2013-04-18 12:10:04

回答

0

你可以用遞歸CTE來做到這一點。請注意,您確實需要爲其添加限制,否則它會愉快地重複到無窮大。

WITH RECURSIVE event_calendar AS (
    SELECT id, coalesce("date", date_repeat_start) as e_date, event_name, 0 AS level 
     FROM events 
    UNION 
    SELECT e.id, ec.e_date + date_repeat_interval, ec.event_name, ec.level + 1 
     FROM events e 
     JOIN event_calendar ec ON e.id = ec.id 
    WHERE ec.level <= 10 and e.date_repeat_start is not null 
      and e.date_repeat_stop >= ec.e_date + date_repeat_interval 
) 
SELECT * FROM event_calendar order by e_date;