使用 postgres generate_series 生成循环计划
Using postgres generate_series to generate a recurring schedule
我有一个 table,其重复日期称为 Events
,我如何利用这个 table 并根据事件 wday 和时间从一系列事件中生成特定的即将到来的日期? (例如只有 wday "mondays" 和开始时间“7pm”很重要)
事件
+-----+---------------------------+---------------------+
| 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和开始时间,忽略实际日期)
为简单起见,您可以忽略循环计划并假设所有事件都是每周一次,例如总是在一周的同一天。
我怎样才能把这样的 table 转换成这样:
未来日志
+----------+---------------------------+
| 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 周的未来日期来构建事件的时间表。
更新的答案:
在 case 语句中使用 generate_series 来构建序列,类似于我在原始答案中所做的,根据列 recurring_schedule
.
不同的频率
指定您希望系列生成的日期作为绝对日期 '2020-01-01'::timestamptz
正如我在下面使用的那样,您可以传递一个相对日期,例如NOW() + INTERVAL '10 weeks'
相反。
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 的语法是
generate_series(start_time, end_time, step_interval)
由于您的日程安排 JSON 包含间隔,您可以这样构造查询,并根据需要添加更多日程安排类型。
WITH test (id, start_at, place_id, recurring_schedule) AS (
VALUES
(358, '2015-01-23 20:00:00 +0000'::TIMESTAMPTZ, 412,
'{"validations":{"day":[2]},"rule_type":"IceCube::WeeklyRule","interval":1,"week_start":0}'::JSONB),
(359, '2016-01-22 19:30:00 +1100', 414,
'{"validations":{"day":[1]},"rule_type":"IceCube::WeeklyRule","interval":1,"week_start":0}'),
(360, '2016-02-01 19:00:00 +1100', 415,
'{"validations":{"day":[4]},"rule_type":"IceCube::WeeklyRule","interval":1,"week_start":0}'),
(361, '2016-02-01 20:00:00 +0000', 416,
'{"validations":{"day":[4]},"rule_type":"IceCube::WeeklyRule","interval":1,"week_start":0}'),
(362, '2014-02-13 20:00:00 +0000', 417,
'{"validations":{"day":[2]},"rule_type":"IceCube::WeeklyRule","interval":1,"week_start":0}')
)
SELECT id, start_at, place_id,
CASE recurring_schedule->>'rule_type'
WHEN 'IceCube::WeeklyRule'
THEN GENERATE_SERIES(start_at, NOW(), (recurring_schedule->>'interval' || ' WEEK')::INTERVAL)
ELSE NULL
END recurring_start_time
FROM test;
我有一个 table,其重复日期称为 Events
,我如何利用这个 table 并根据事件 wday 和时间从一系列事件中生成特定的即将到来的日期? (例如只有 wday "mondays" 和开始时间“7pm”很重要)
事件
+-----+---------------------------+---------------------+
| 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和开始时间,忽略实际日期)
为简单起见,您可以忽略循环计划并假设所有事件都是每周一次,例如总是在一周的同一天。
我怎样才能把这样的 table 转换成这样:
未来日志
+----------+---------------------------+
| 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 周的未来日期来构建事件的时间表。
更新的答案:
在 case 语句中使用 generate_series 来构建序列,类似于我在原始答案中所做的,根据列 recurring_schedule
.
指定您希望系列生成的日期作为绝对日期 '2020-01-01'::timestamptz
正如我在下面使用的那样,您可以传递一个相对日期,例如NOW() + INTERVAL '10 weeks'
相反。
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 的语法是
generate_series(start_time, end_time, step_interval)
由于您的日程安排 JSON 包含间隔,您可以这样构造查询,并根据需要添加更多日程安排类型。
WITH test (id, start_at, place_id, recurring_schedule) AS (
VALUES
(358, '2015-01-23 20:00:00 +0000'::TIMESTAMPTZ, 412,
'{"validations":{"day":[2]},"rule_type":"IceCube::WeeklyRule","interval":1,"week_start":0}'::JSONB),
(359, '2016-01-22 19:30:00 +1100', 414,
'{"validations":{"day":[1]},"rule_type":"IceCube::WeeklyRule","interval":1,"week_start":0}'),
(360, '2016-02-01 19:00:00 +1100', 415,
'{"validations":{"day":[4]},"rule_type":"IceCube::WeeklyRule","interval":1,"week_start":0}'),
(361, '2016-02-01 20:00:00 +0000', 416,
'{"validations":{"day":[4]},"rule_type":"IceCube::WeeklyRule","interval":1,"week_start":0}'),
(362, '2014-02-13 20:00:00 +0000', 417,
'{"validations":{"day":[2]},"rule_type":"IceCube::WeeklyRule","interval":1,"week_start":0}')
)
SELECT id, start_at, place_id,
CASE recurring_schedule->>'rule_type'
WHEN 'IceCube::WeeklyRule'
THEN GENERATE_SERIES(start_at, NOW(), (recurring_schedule->>'interval' || ' WEEK')::INTERVAL)
ELSE NULL
END recurring_start_time
FROM test;