使用postgres generate_series生成定期计划

时间:2018-04-10 13:50:43

标签: postgresql postgresql-9.4 generate-series

我有一个名为Events的定期日期表,如何根据事件的日期和时间从这个表中生成特定的即将到来的日期? (例如,只有wday“星期一”和开始时间“晚上7点”很重要)

事件

+-----+---------------------------+---------------------+
| id  | start_at                  | recurring_schedule  |
+-----+---------------------------+---------------------+
| 358 | 2015-01-23 20:00:00 +0000 | Weekly              |
| 359 | 2016-01-22 19:30:00 +1100 | Monthly             |
| 360 | 2016-02-01 19:00:00 +1100 | Weekly              |
| 361 | 2016-02-01 20:00:00 +0000 | Weekly              |
| 362 | 2014-02-13 20:00:00 +0000 | Bi-Weekly           |
+-----+---------------------------+---------------------+
  • start_at(日期时间,用于DOW和开始时间,忽略实际日期)

为简单起见,您可以忽略定期计划,只假设所有事件都是每周一次,例如总是在一周的同一天。

我怎样才能把这样的表格转换成这样的表格:

FutureLog

+----------+---------------------------+
| event_id | start_at                  |
+----------+---------------------------+
| 35       | 2018-04-11 19:30:00 +0000 |
| 94       | 2018-04-12 20:00:00 +0100 |
| 269      | 2018-04-13 18:30:00 +0100 |
| 45       | 2018-04-13 20:00:00 +0100 |
| 242      | 2018-04-13 19:30:00 +1100 |    
| 35       | 2018-04-18 19:30:00 +0000 |
| 94       | 2018-04-19 20:00:00 +0100 |
| 269      | 2018-04-20 18:30:00 +0100 |
| 45       | 2018-04-20 20:00:00 +0100 |
| 242      | 2018-04-20 19:30:00 +1100 |
+----------+---------------------------+

例如,我希望SELECT FROM events理论事件,并使用类似generate_series之类的东西来构建事件时间表,从每个事件创建6-8周的未来日期。

1 个答案:

答案 0 :(得分:2)

更新回答:

在case语句中使用generate_series来构建序列,就像我在原始答案中所做的那样,根据列<UserInputType>TextBox</UserInputType>改变频率。

指定您希望系列生成的日期为绝对日期recurring_schedule,如我在下面使用的那样,您可以传递相对日期,例如而是'2020-01-01'::timestamptz

NOW() + INTERVAL '10 weeks'

带有json字段的架构的原始答案:

datetime类型的generate_series的语法是

SELECT id event_id, start_at, 
CASE recurring_schedule 
    WHEN 'Weekly' 
        THEN GENERATE_SERIES(start_at, '2020-01-01'::timestamptz, '1 weeks'::INTERVAL)
    WHEN 'Bi-Weekly'
        THEN GENERATE_SERIES(start_at, '2020-01-01'::timestamptz, '2 weeks'::INTERVAL)
    WHEN 'Monthly'
        THEN GENERATE_SERIES(start_at, '2020-01-01'::timestamptz, '1 month'::INTERVAL)
    ELSE NULL 
END recurring_start_time
FROM events;

由于您的日程安排在JSON中包含间隔,您可以构建查询,并根据需要添加更多日程表类型。

generate_series(start_time, end_time, step_interval)