Crie uma tabela de exemplo:
CREATE TEMP TABLE foo (id int, a text, b text, c text);
INSERT INTO foo VALUES (1, 'ant', 'cat', 'chimp'), (2, 'grape', 'mint', 'basil');
Você pode 'unpivot' ou 'uncrosstab' usando UNION ALL:
SELECT id,
'a' AS colname,
a AS thing
FROM foo
UNION ALL
SELECT id,
'b' AS colname,
b AS thing
FROM foo
UNION ALL
SELECT id,
'c' AS colname,
c AS thing
FROM foo
ORDER BY id;
Isso executa 3 subconsultas diferentes em
foo
, um para cada coluna que queremos desdinamizar e retorna, em uma tabela, todos os registros de cada uma das subconsultas. Mas isso irá varrer a tabela N vezes, onde N é o número de colunas que você deseja desdinamizar. Isso é ineficiente e um grande problema quando, por exemplo, você está trabalhando com uma tabela muito grande que leva muito tempo para varrer.
Em vez disso, use:
SELECT id,
unnest(array['a', 'b', 'c']) AS colname,
unnest(array[a, b, c]) AS thing
FROM foo
ORDER BY id;
Isso é mais fácil de escrever e só irá varrer a tabela uma vez.
array[a, b, c]
retorna um objeto array, com os valores de a, b e c como seus elementos.unnest(array[a, b, c])
divide os resultados em uma linha para cada um dos elementos da matriz. Espero que ajude!