sql >> Base de Datos >  >> RDS >> PostgreSQL

Equivalente a unpivot() en PostgreSQL

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!