很难完成下面列出的转置表:
ID Type Col1 Col2 Col3
----------------------------
1 a 5 2 3
1 b 2 1 3
2 a 4 4 3
2 c 7 6 4
结果应如下所示:
ID Col a b c
----------------------------
1 Col1 5 2 null
1 Col2 2 1 null
1 Col3 3 3 null
2 Col1 4 null 7
2 Col2 4 null 6
2 Col3 3 null 4
这里有很多类似的问题,但在我看来它们与我所需的问题略有不同,因为我希望将ID保留在结果集中。 试图使用tablefunc扩展没有运气。 有什么想法要怎么做?
答案 0 :(得分:0)
通常,我认为列名中的大写字母是有害的,因此我忽略了您的请求中的那部分。
您的数据:
create temp table d(id int,type text,col1 int,col2 int ,col3 int);
insert into d values (1,'a',5,2,3),(1,'b',2,1,3),(2,'a',4,4,3),(2,'c',7,6,4);
一种实现方法是转换为EAV,然后对此进行枢纽操作:
with eav as (
select id,type,'col1' as col,col1 as val from d
union all
select id,type,'col2',col2 from d
union all
select id,type,'col3',col3 from d)
, ca as (select id,col, val from eav where type='a')
, cb as (select id,col, val from eav where type='b')
, cc as (select id,col, val from eav where type='c')
select id,col,ca.val as a ,cb.val as b, cc.val as c
from ca
full outer join cb using (id,col)
full outer join cc using (id,col)
order by id,col;
结果:(在\pset null 'null' in psql
之后)
id | col | a | b | c
----+------+---+------+------
1 | col1 | 5 | 2 | null
1 | col2 | 2 | 1 | null
1 | col3 | 3 | 3 | null
2 | col1 | 4 | null | 7
2 | col2 | 4 | null | 6
2 | col3 | 3 | null | 4
或者可以这样排列:
with eav as (
select id,type,'col1' as col,col1 as val from d
union all
select id,type,'col2',col2 from d
union all
select id,type,'col3',col3 from d)
, ca as (select id,col, val as a from eav where type='a')
, cb as (select id,col, val as b from eav where type='b')
, cc as (select id,col, val as c from eav where type='c')
select *
from ca
full outer join cb using (id,col)
full outer join cc using (id,col)
order by id,col;
答案 1 :(得分:0)
SELECT
id,
key as col,
max(value::int) FILTER (WHERE type = 'a') as a,
max(value::int) FILTER (WHERE type = 'b') as b,
max(value::int) FILTER (WHERE type = 'c') as c
FROM
table,
jsonb_each_text(
jsonb_build_object('col1', col1, 'col2', col2, 'col3', col3)
)
GROUP BY id, key
ORDER BY id, key
主要思想是我需要将三列(及其值作为键/值对)与id
列交叉连接。键/值对使我有了JSON的主意。使用JSON功能,您可以创建JSON对象(jsonb_build_object()
)
id type col1 col2 col3 jsonb_build_object
1 a 5 2 3 {"col1": 5, "col2": 2, "col3": 3}
1 b 2 1 3 {"col1": 2, "col2": 1, "col3": 3}
2 a 4 4 3 {"col1": 4, "col2": 4, "col3": 3}
2 c 7 6 4 {"col1": 7, "col2": 6, "col3": 4}
使用jsonb_each_text
,您可以将JSON对象扩展为每个元素一行,并为键和值添加一个额外的列(作为文本列):
id type (...) key value
1 a col1 5
1 a col2 2
1 a col3 3
1 b col1 2
1 b col2 1
1 b col3 3
2 a col1 4
2 a col2 4
2 a col3 3
2 c col1 7
2 c col2 6
2 c col3 4
其余只是分组和过滤(做一些简单的透视)。