为每个 id 生成日期系列
Generate date series for each id
我有一个包含四列的 table。我想为从 date1
到 date3
的每个 id
创建一个间隔为 1 天的日期列。如果没有date3
那么到date2
,如果没有date2
,那么只有date1
.
如何在 Postgres 中实现这一点?谢谢!
示例数据:
+-------+---------------------+---------------------+---------------------+
| id | date1 | date2 | date3 |
+-------+---------------------+---------------------+---------------------+
| 76efg | 2021-01-03 06:33:54 | 2021-01-07 05:19:03 | 2021-01-08 05:19:03 |
| b67cs | 2021-01-09 03:45:24 | 2021-01-14 06:55:13 | |
| fsf56 | 2021-01-25 11:18:03 | 2021-01-25 11:18:03 | |
| ghl56 | 2021-01-29 14:25:57 | 2021-02-02 17:37:10 | 2021-02-18 01:13:37 |
| 90tum | 2021-02-18 06:13:30 | | |
+-------+---------------------+---------------------+---------------------+
id '76efg' 的期望输出:
+-------+--------------+---------------------+---------------------+---------------------+--+
| id | date_created | date1 | date2 | date3 | |
+-------+--------------+---------------------+---------------------+---------------------+--+
| 76efg | 2021-01-03 | 2021-01-03 06:33:54 | 2021-01-07 05:19:03 | 2021-01-08 05:19:03 | |
| 76efg | 2021-01-04 | 2021-01-03 06:33:54 | 2021-01-07 05:19:03 | 2021-01-08 05:19:03 | |
| 76efg | 2021-01-05 | 2021-01-03 06:33:54 | 2021-01-07 05:19:03 | 2021-01-08 05:19:03 | |
| 76efg | 2021-01-06 | 2021-01-03 06:33:54 | 2021-01-07 05:19:03 | 2021-01-08 05:19:03 | |
| 76efg | 2021-01-07 | 2021-01-03 06:33:54 | 2021-01-07 05:19:03 | 2021-01-08 05:19:03 | |
| 76efg | 2021-01-08 | 2021-01-03 06:33:54 | 2021-01-07 05:19:03 | 2021-01-08 05:19:03 | |
+-------+--------------+---------------------+---------------------+---------------------+--+
您是否尝试过使用 generated_series()
? The following query generates a series of timestamps based on date1
,date2
and date3
, and the limit of the series found using COALESCE
- 基本上检查列是否为 null
.
WITH j (id,date1,date2,date3) AS (
VALUES ('76efg',
'2021-01-03 06:33:54'::TIMESTAMP,
'2021-01-07 05:19:03'::TIMESTAMP,
'2021-01-08 05:19:03'::TIMESTAMP ),
('b67cs',
'2021-01-09 03:45:24'::TIMESTAMP,
'2021-01-14 06:55:13'::TIMESTAMP,
NULL),
('90tum','2021-02-18 06:13:30'::TIMESTAMP,
NULL,NULL)
)
SELECT
id,
generate_series(
date1,
COALESCE(date3,date2,date1),'1 day'::INTERVAL) AS date_created,
date2,
date3
FROM j;
id | date_created | date2 | date3
-------+---------------------+---------------------+---------------------
76efg | 2021-01-03 06:33:54 | 2021-01-07 05:19:03 | 2021-01-08 05:19:03
76efg | 2021-01-04 06:33:54 | 2021-01-07 05:19:03 | 2021-01-08 05:19:03
76efg | 2021-01-05 06:33:54 | 2021-01-07 05:19:03 | 2021-01-08 05:19:03
76efg | 2021-01-06 06:33:54 | 2021-01-07 05:19:03 | 2021-01-08 05:19:03
76efg | 2021-01-07 06:33:54 | 2021-01-07 05:19:03 | 2021-01-08 05:19:03
b67cs | 2021-01-09 03:45:24 | 2021-01-14 06:55:13 |
b67cs | 2021-01-10 03:45:24 | 2021-01-14 06:55:13 |
b67cs | 2021-01-11 03:45:24 | 2021-01-14 06:55:13 |
b67cs | 2021-01-12 03:45:24 | 2021-01-14 06:55:13 |
b67cs | 2021-01-13 03:45:24 | 2021-01-14 06:55:13 |
b67cs | 2021-01-14 03:45:24 | 2021-01-14 06:55:13 |
90tum | 2021-02-18 06:13:30 | |
检查此 db<>fiddle
。
感谢@clamp 关于 COALESCE
:
的提示
COALESCE(COALESCE(date3,date2),date1) is equivalent to COALESCE(date3,date2,date1)
我有一个包含四列的 table。我想为从 date1
到 date3
的每个 id
创建一个间隔为 1 天的日期列。如果没有date3
那么到date2
,如果没有date2
,那么只有date1
.
如何在 Postgres 中实现这一点?谢谢!
示例数据:
+-------+---------------------+---------------------+---------------------+
| id | date1 | date2 | date3 |
+-------+---------------------+---------------------+---------------------+
| 76efg | 2021-01-03 06:33:54 | 2021-01-07 05:19:03 | 2021-01-08 05:19:03 |
| b67cs | 2021-01-09 03:45:24 | 2021-01-14 06:55:13 | |
| fsf56 | 2021-01-25 11:18:03 | 2021-01-25 11:18:03 | |
| ghl56 | 2021-01-29 14:25:57 | 2021-02-02 17:37:10 | 2021-02-18 01:13:37 |
| 90tum | 2021-02-18 06:13:30 | | |
+-------+---------------------+---------------------+---------------------+
id '76efg' 的期望输出:
+-------+--------------+---------------------+---------------------+---------------------+--+
| id | date_created | date1 | date2 | date3 | |
+-------+--------------+---------------------+---------------------+---------------------+--+
| 76efg | 2021-01-03 | 2021-01-03 06:33:54 | 2021-01-07 05:19:03 | 2021-01-08 05:19:03 | |
| 76efg | 2021-01-04 | 2021-01-03 06:33:54 | 2021-01-07 05:19:03 | 2021-01-08 05:19:03 | |
| 76efg | 2021-01-05 | 2021-01-03 06:33:54 | 2021-01-07 05:19:03 | 2021-01-08 05:19:03 | |
| 76efg | 2021-01-06 | 2021-01-03 06:33:54 | 2021-01-07 05:19:03 | 2021-01-08 05:19:03 | |
| 76efg | 2021-01-07 | 2021-01-03 06:33:54 | 2021-01-07 05:19:03 | 2021-01-08 05:19:03 | |
| 76efg | 2021-01-08 | 2021-01-03 06:33:54 | 2021-01-07 05:19:03 | 2021-01-08 05:19:03 | |
+-------+--------------+---------------------+---------------------+---------------------+--+
您是否尝试过使用 generated_series()
? The following query generates a series of timestamps based on date1
,date2
and date3
, and the limit of the series found using COALESCE
- 基本上检查列是否为 null
.
WITH j (id,date1,date2,date3) AS (
VALUES ('76efg',
'2021-01-03 06:33:54'::TIMESTAMP,
'2021-01-07 05:19:03'::TIMESTAMP,
'2021-01-08 05:19:03'::TIMESTAMP ),
('b67cs',
'2021-01-09 03:45:24'::TIMESTAMP,
'2021-01-14 06:55:13'::TIMESTAMP,
NULL),
('90tum','2021-02-18 06:13:30'::TIMESTAMP,
NULL,NULL)
)
SELECT
id,
generate_series(
date1,
COALESCE(date3,date2,date1),'1 day'::INTERVAL) AS date_created,
date2,
date3
FROM j;
id | date_created | date2 | date3
-------+---------------------+---------------------+---------------------
76efg | 2021-01-03 06:33:54 | 2021-01-07 05:19:03 | 2021-01-08 05:19:03
76efg | 2021-01-04 06:33:54 | 2021-01-07 05:19:03 | 2021-01-08 05:19:03
76efg | 2021-01-05 06:33:54 | 2021-01-07 05:19:03 | 2021-01-08 05:19:03
76efg | 2021-01-06 06:33:54 | 2021-01-07 05:19:03 | 2021-01-08 05:19:03
76efg | 2021-01-07 06:33:54 | 2021-01-07 05:19:03 | 2021-01-08 05:19:03
b67cs | 2021-01-09 03:45:24 | 2021-01-14 06:55:13 |
b67cs | 2021-01-10 03:45:24 | 2021-01-14 06:55:13 |
b67cs | 2021-01-11 03:45:24 | 2021-01-14 06:55:13 |
b67cs | 2021-01-12 03:45:24 | 2021-01-14 06:55:13 |
b67cs | 2021-01-13 03:45:24 | 2021-01-14 06:55:13 |
b67cs | 2021-01-14 03:45:24 | 2021-01-14 06:55:13 |
90tum | 2021-02-18 06:13:30 | |
检查此 db<>fiddle
。
感谢@clamp 关于 COALESCE
:
COALESCE(COALESCE(date3,date2),date1) is equivalent to COALESCE(date3,date2,date1)