Как преобразовать столбцы данных в один столбец, где каждая строка данных укладывается вертикально в этом столбце (в Postgres)?

#sql #postgresql #unpivot

#sql #postgresql #отменить

Вопрос:

У нас есть горизонтальное представление данных, подобное этому:

 |id|col1|col2|col3|col4|col5|
|01|1111|2222|3333|4444|5555|
|02|1234|5678|9012|3456|7890|
...
  

Я хотел бы преобразовать его в это:

 |id|col|col_data|
|01|  1|    1111|
|01|  2|    2222|
|01|  3|    3333|
|01|  4|    4444|
|01|  5|    5555|
|02|  1|    1234|
|02|  2|    5678|
|02|  3|    9012|
|02|  4|    3456|
|02|  5|    7890|
....
  

Я смог правильно перечислить |id|col| столбцы моей целевой таблицы, используя это:

 SELECT 
    id,
    unnest((
        select
            array_agg(split_part(column_name::text, 'l', 2)::numeric)
        FROM INFORMATION_SCHEMA.columns
        WHERE 
            TABLE_NAME = 'my_table' and 
            TABLE_SCHEMA = 'my_schema'
    )) AS "col"
FROM my_schema.my_table
group by "col" id
ORDER BY id, "col";
  

Но я не знаю, как получить данные из исходной таблицы в нужном формате.

К вашему СВЕДЕНИЮ:

  • У меня нет прав суперпользователя.
  • Фактическая таблица содержит 26 столбцов

Ответ №1:

Одним из способов является боковое соединение, если все столбцы имеют один и тот же тип данных:

 select t.id, up.*
from the_table t
  cross join lateral (
    values (1, col1), (2, col2), (3, col3), (4, col4), (5, col5)
  ) as up(col, col_data);
  

Если вас не волнует, что все преобразуется в текст (без сохранения исходных типов данных), вы можете использовать JSON для отключения столбцов:

 select t.id, 
       up.col, 
       up.col_data
from the_table t
  cross join jsonb_each_text(to_jsonb(t) - 'id') as up(col, col_data)