将日期范围更改为具有离散日期的新行
Change a date range into new rows with discrete dates
我有一个 table,其中包含 name
、location
、start_date
和 end_date
。我希望将这些包含日期范围的行转换为离散日期的行,同时保持相应的行信息不变。
示例:
Name1, Location1, 2015-4-01, 2015-4-04
变为:
Name1, Location1, 2015-4-01
Name1, Location1, 2015-4-02
Name1, Location1, 2015-4-03
Name1, Location1, 2015-4-04
我想我需要使用 PostgreSQL 函数将其创建为一个新的 table。
使用三个必需的列创建一个新的 table:
CREATE TABLE new_tbl (
nam varchar,
loc varchar,
dt date);
由于您希望在 start_date
- end_date
范围内的新 table 中记录包含一天的时间间隔,包括在内,最简单的解决方案是从您的日期:
generate_series(start_date::timestamp, end_date::timestamp, '1 day')
这你可以简单地在新 table 上插入一个 INSERT
语句:
INSERT INTO new_tbl
SELECT nam, loc, generate_series(start_date::timestamp, end_date::timestamp, '1 day')::date
FROM old_tbl;
由于 generate_series
函数使用 timestamp
参数,您需要显式转换 date
s,然后将生成的 timestamp
s 转换回 date
s 以匹配您的列定义。
在现代 Postgres (9.3+) 中,最好在 LATERAL
连接中使用集合返回函数 FROM
列表:
假设 start_date
和 end_date
已定义 NOT NULL
:
CREATE TABLE AS
SELECT name, location, day::date
FROM tbl, generate_series(start_date, end_date, interval '1 day') day;
LATERAL
在这里隐含。
The manual about LATERAL
subqueries.
一些相关的回答(有很多):
- Calculate working hours between 2 dates in PostgreSQL
关于LATERAL
(回复评论):
- PostgreSQL unnest() with element number
我有一个 table,其中包含 name
、location
、start_date
和 end_date
。我希望将这些包含日期范围的行转换为离散日期的行,同时保持相应的行信息不变。
示例:
Name1, Location1, 2015-4-01, 2015-4-04
变为:
Name1, Location1, 2015-4-01
Name1, Location1, 2015-4-02
Name1, Location1, 2015-4-03
Name1, Location1, 2015-4-04
我想我需要使用 PostgreSQL 函数将其创建为一个新的 table。
使用三个必需的列创建一个新的 table:
CREATE TABLE new_tbl (
nam varchar,
loc varchar,
dt date);
由于您希望在 start_date
- end_date
范围内的新 table 中记录包含一天的时间间隔,包括在内,最简单的解决方案是从您的日期:
generate_series(start_date::timestamp, end_date::timestamp, '1 day')
这你可以简单地在新 table 上插入一个 INSERT
语句:
INSERT INTO new_tbl
SELECT nam, loc, generate_series(start_date::timestamp, end_date::timestamp, '1 day')::date
FROM old_tbl;
由于 generate_series
函数使用 timestamp
参数,您需要显式转换 date
s,然后将生成的 timestamp
s 转换回 date
s 以匹配您的列定义。
在现代 Postgres (9.3+) 中,最好在 LATERAL
连接中使用集合返回函数 FROM
列表:
假设 start_date
和 end_date
已定义 NOT NULL
:
CREATE TABLE AS
SELECT name, location, day::date
FROM tbl, generate_series(start_date, end_date, interval '1 day') day;
LATERAL
在这里隐含。
The manual about LATERAL
subqueries.
一些相关的回答(有很多):
- Calculate working hours between 2 dates in PostgreSQL
关于LATERAL
(回复评论):
- PostgreSQL unnest() with element number