Cree una tabla de ejemplo:
CREATE TEMP TABLE foo (id int, a text, b text, c text);
INSERT INTO foo VALUES (1, 'ant', 'cat', 'chimp'), (2, 'grape', 'mint', 'basil');
Puede 'quitar pivote' o 'quitar tabulación cruzada' 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;
Esto ejecuta 3 subconsultas diferentes en foo
, uno para cada columna que queremos descentrar y devuelve, en una tabla, todos los registros de cada una de las subconsultas.
Pero eso escaneará la tabla N veces, donde N es la cantidad de columnas que desea deshacer. Esto es ineficiente y un gran problema cuando, por ejemplo, está trabajando con una tabla muy grande que lleva mucho tiempo escanear.
En su lugar, utilice:
SELECT id,
unnest(array['a', 'b', 'c']) AS colname,
unnest(array[a, b, c]) AS thing
FROM foo
ORDER BY id;
Esto es más fácil de escribir y solo escaneará la tabla una vez.
array[a, b, c]
devuelve un objeto de matriz, con los valores de a, b y c como elementos.unnest(array[a, b, c])
divide los resultados en una fila para cada uno de los elementos de la matriz.
¡Espero que eso ayude!