[英]convert data wide to long with make sequential date in postgresql
I have data frame with date like below:我有如下日期的数据框:
id start_date end_date product supply_per_day
1 2020-03-01 2020-03-01 A 10
1 2020-03-01 2020-03-01 B 10
1 2020-03-01 2020-03-02 A 5
2 2020-02-28 2020-03-02 A 10
2 2020-03-01 2020-03-03 B 4
2 2020-03-02 2020-03-05 A 5
I want make this data wide to long like:我想让这些数据变得很长,比如:
id date product supply_per_day
1 2020-03-01 A 10
1 2020-03-01 B 10
1 2020-03-01 A 5
1 2020-03-02 A 5
2 2020-02-28 A 10
2 2020-03-01 A 10
2 2020-03-02 A 10
2 2020-03-01 B 4
2 2020-03-02 B 4
2 2020-03-03 B 4
2 2020-03-02 B 5
2 2020-03-03 B 5
2 2020-03-04 B 5
2 2020-03-05 B 5
give me some idea please请给我一些想法
For Oracle 12c and later, you can use:对于 Oracle 12c 及更高版本,您可以使用:
SELECT t.id,
d.dt,
t.product,
t.supply_per_day
FROM table_name t
OUTER APPLY(
SELECT start_date + LEVEL - 1 AS dt
FROM DUAL
CONNECT BY start_date + LEVEL - 1 <= end_date
) d
Which, for the sample data:其中,对于样本数据:
CREATE TABLE table_name ( id, start_date, end_date, product, supply_per_day ) AS
SELECT 1, DATE '2020-03-01', DATE '2020-03-01', 'A', 10 FROM DUAL UNION ALL
SELECT 1, DATE '2020-03-01', DATE '2020-03-01', 'B', 10 FROM DUAL UNION ALL
SELECT 1, DATE '2020-03-01', DATE '2020-03-02', 'A', 5 FROM DUAL UNION ALL
SELECT 2, DATE '2020-02-28', DATE '2020-03-02', 'A', 10 FROM DUAL UNION ALL
SELECT 2, DATE '2020-03-01', DATE '2020-03-03', 'B', 4 FROM DUAL UNION ALL
SELECT 2, DATE '2020-03-02', DATE '2020-03-05', 'A', 5 FROM DUAL;
Outputs:输出:
ID ID | DT DT | PRODUCT产品 | SUPPLY_PER_DAY SUPPLY_PER_DAY |
---|---|---|---|
1 1 | 2020-03-01 00:00:00 2020-03-01 00:00:00 | A一个 | 10 10 |
1 1 | 2020-03-01 00:00:00 2020-03-01 00:00:00 | B乙 | 10 10 |
1 1 | 2020-03-01 00:00:00 2020-03-01 00:00:00 | A一个 | 5 5 |
1 1 | 2020-03-02 00:00:00 2020-03-02 00:00:00 | A一个 | 5 5 |
2 2 | 2020-02-28 00:00:00 2020-02-28 00:00:00 | A一个 | 10 10 |
2 2 | 2020-02-29 00:00:00 2020-02-29 00:00:00 | A一个 | 10 10 |
2 2 | 2020-03-01 00:00:00 2020-03-01 00:00:00 | A一个 | 10 10 |
2 2 | 2020-03-02 00:00:00 2020-03-02 00:00:00 | A一个 | 10 10 |
2 2 | 2020-03-01 00:00:00 2020-03-01 00:00:00 | B乙 | 4 4 |
2 2 | 2020-03-02 00:00:00 2020-03-02 00:00:00 | B乙 | 4 4 |
2 2 | 2020-03-03 00:00:00 2020-03-03 00:00:00 | B乙 | 4 4 |
2 2 | 2020-03-02 00:00:00 2020-03-02 00:00:00 | A一个 | 5 5 |
2 2 | 2020-03-03 00:00:00 2020-03-03 00:00:00 | A一个 | 5 5 |
2 2 | 2020-03-04 00:00:00 2020-03-04 00:00:00 | A一个 | 5 5 |
2 2 | 2020-03-05 00:00:00 2020-03-05 00:00:00 | A一个 | 5 5 |
In Postgres you can use generate_series()
for this:在 Postgres 中,您可以为此使用generate_series()
:
select t.id, g.day::date as date, t.product, t.supply_per_day
from the_table t
cross join generate_series(t.start_date, t.end_date, interval '1 day') as g(day)
order by t.id, g.day
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.