Postgres 将长格式转换为宽格式
Postgres convert long to wide format
很抱歉,如果这个问题以前有人回答过,请随时指给我看,但我找不到一个基本的、干净的答案(我觉得应该是)一个相对基本的问题。
我想将 postgres table 从长格式转换为宽格式。
假设我有一个 table...
date
value
id
2022-01-01
100
1
2022-01-02
200
1
2022-01-03
300
1
2022-01-01
100
2
2022-01-02
200
2
2022-01-03
300
2
2022-01-01
100
3
2022-01-02
200
3
2022-01-03
300
3
我想将其输出为...
date
id_1_value
id_2_value
id_3_value
2022-01-01
100
100
100
2022-01-02
200
200
200
2022-01-03
300
300
300
如果您要回答,我想非常清楚地将 ID 转换为列的方式需要是动态的。例如,如果我对具有 100 个我事先不知道的不同 ID 的 table 执行此操作,则解决方案应该能够优雅地处理这个问题。
您所描述的 PIVOT 为 table。虽然这可以在 SQL 中完成,但它很乏味且容易出错,并且需要 a priori 对结果列的了解。如果添加了数据值,则需要重写查询(即将 id 4 添加到 table)。下面是一个例子。
with test_data ( dt, val, id) as
(values (date '2022-01-01', 100, 1)
, (date '2022-01-02', 200, 1)
, (date '2022-01-03', 300, 1)
, (date '2022-01-01', 100, 2)
, (date '2022-01-02', 200, 2)
, (date '2022-01-03', 300, 2)
, (date '2022-01-01', 100, 3)
, (date '2022-01-02', 200, 3)
, (date '2022-01-03', 300, 3)
)
-- your query begins here
select dt, max(id_1_value), max(id_2_value), max(id_3_value)
from (
select dt
, case when id = 1 then val else null end id_1_value
, case when id = 2 then val else null end id_2_value
, case when id = 3 then val else null end id_3_value
from test_data
) sq
group by dt
order by dt;
作为替代方案,您可能需要研究 crosstab 函数。
虽然 SQL 能够创建 PIVOT,但它并非为此而设计。这个还是最好留给你的application presentation manager;
很抱歉,如果这个问题以前有人回答过,请随时指给我看,但我找不到一个基本的、干净的答案(我觉得应该是)一个相对基本的问题。
我想将 postgres table 从长格式转换为宽格式。
假设我有一个 table...
date | value | id |
---|---|---|
2022-01-01 | 100 | 1 |
2022-01-02 | 200 | 1 |
2022-01-03 | 300 | 1 |
2022-01-01 | 100 | 2 |
2022-01-02 | 200 | 2 |
2022-01-03 | 300 | 2 |
2022-01-01 | 100 | 3 |
2022-01-02 | 200 | 3 |
2022-01-03 | 300 | 3 |
我想将其输出为...
date | id_1_value | id_2_value | id_3_value |
---|---|---|---|
2022-01-01 | 100 | 100 | 100 |
2022-01-02 | 200 | 200 | 200 |
2022-01-03 | 300 | 300 | 300 |
如果您要回答,我想非常清楚地将 ID 转换为列的方式需要是动态的。例如,如果我对具有 100 个我事先不知道的不同 ID 的 table 执行此操作,则解决方案应该能够优雅地处理这个问题。
您所描述的 PIVOT 为 table。虽然这可以在 SQL 中完成,但它很乏味且容易出错,并且需要 a priori 对结果列的了解。如果添加了数据值,则需要重写查询(即将 id 4 添加到 table)。下面是一个例子。
with test_data ( dt, val, id) as
(values (date '2022-01-01', 100, 1)
, (date '2022-01-02', 200, 1)
, (date '2022-01-03', 300, 1)
, (date '2022-01-01', 100, 2)
, (date '2022-01-02', 200, 2)
, (date '2022-01-03', 300, 2)
, (date '2022-01-01', 100, 3)
, (date '2022-01-02', 200, 3)
, (date '2022-01-03', 300, 3)
)
-- your query begins here
select dt, max(id_1_value), max(id_2_value), max(id_3_value)
from (
select dt
, case when id = 1 then val else null end id_1_value
, case when id = 2 then val else null end id_2_value
, case when id = 3 then val else null end id_3_value
from test_data
) sq
group by dt
order by dt;
作为替代方案,您可能需要研究 crosstab 函数。
虽然 SQL 能够创建 PIVOT,但它并非为此而设计。这个还是最好留给你的application presentation manager;