Этот процесс также известен как UNPIVOT и может быть выполнен следующим образом в Postgres:
select up.*
from the_table
cross join lateral (
values
('col_a', col_a),
('col_b', col_b),
('col_c', col_c),
('col_d', col_d)
) as up(category, value);
Обратите внимание, что это работает, только если все столбцы имеют одинаковый тип данных.
Если выне возражайте против потери типа данных (или если столбцы имеют разные типы, и вам все равно нужно привести их к text
), вы можете сделать это динамическим, используя функции JSON:
select up.*
from the_table tt
cross join lateral jsonb_each_text(to_jsonb(tt)) as up;
Если вызная, что все значения могут быть приведены к одному и тому же типу, вы можете использовать:
select up.category,
up.value::float
from the_table tt
cross join lateral jsonb_each_text(to_jsonb(tt)) as up(category, value);
Онлайн пример: https://rextester.com/SHOY36906
Если вам нужно сопоставить столбец «значение» сИсходный первичный ключ таблицы, вы можете сделать что-то вроде этого (при условии, что первичный ключ имеет имя id
)
select tt.id, up.*
from the_table tt
cross join lateral jsonb_each_text(to_jsonb(tt) - 'id') as up(category, value)
order by tt.id;
Онлайн пример: https://rextester.com/MSXD50860