Postgres转置一行

Postgres transpose a row

我有一个 table 如下所示:-

a    b   c   d   e 
29  14  11  16   8 

我想在 Postgres 中将其转换为以下形式:

a 29
b 14
c 11
d 16
e 8

我知道我应该使用 pivot 操作来执行此操作,但我想不出正确的语法来完成此操作。

如能提供帮助,我们将不胜感激。

那就是:

select 'a' as column_name, a as value from mytable
union all
select 'b' as column_name, b as value from mytable
union all
select 'c' as column_name, c as value from mytable
union all
select 'd' as column_name, d as value from mytable
union all
select 'e' as column_name, e as value from mytable

但是在 table 中有多个行你再也看不到了,哪个 a 与哪个 b 相关,等等。所以虽然这符合你的要求,但你可能想一想,这是否真的是你想要做的。

您可以使用横向交叉连接:

select l.*
from the_table t
  cross join lateral (
     values ('a', a), ('b', b), ('c', c) ('d', d)
  ) as l(column_name, value);

另一种选择是将行转换为 JSON 值,然后使用 jsonb_each_text() 提取键值对。这有点动态,但缺点是您需要将值转换回整数:

select l.column_name,
       l.value::int as value
from the_table t
  cross join lateral jsonb_each_text(to_jsonb(t)) as l(column_name, value);

如果您在 table 中有一个主(或唯一)键列,您可能希望将其添加到 SELECT 列表 (select t.id, l.* ...),所以您知道每个值来自哪一行。