2013-04-18 108 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;