2011-09-27 45 views
10

Soy nuevo en PostgreSQL.Cómo hacer un pivote en PostgreSQL

Supongamos que tengo una tabla como bajo

colorname Hexa rgb rgbvalue 
Violet #8B00FF r 139 
Violet #8B00FF g 0 
Violet #8B00FF b 255 
Indigo #4B0082 r 75 
Indigo #4B0082 g 0 
Indigo #4B0082 b 130 
Blue #0000FF r 0 
Blue #0000FF g 0 
Blue #0000FF b 255 

Si hago un pivote en SQL Server como

SELECT colorname,hexa,[r], [g], [b] 
FROM 
(SELECT colorname,hexa,rgb,rgbvalue 
    FROM tblPivot) AS TableToBePivoted 
PIVOT 
(
sum(rgbvalue) 
FOR rgb IN ([r], [g], [b]) 
) AS PivotedTable; 

consigo la salida como

colorname hexa r g b 
Blue #0000FF 0 0 255 
Indigo #4B0082 75 0 130 
Violet #8B00FF 139 0 255 

Cómo hacer el lo mismo usando PostgreSQL?

Mi intento es

SELECT * 
FROM crosstab 
(
    'SELECT 
     colorname 
     ,hexa 
     ,rgb 
     ,rgbvalue 
    FROM tblPivot' 
)AS ct(colorname text, hexa text, rgb text, rgbvalue int); 

Pero que consigue error:

ERROR: function crosstab(unknown) does not exist 
LINE 2: FROM crosstab 
      ^
HINT: No function matches the given name and argument types. You might need to add explicit type casts. 
********** Error ********** 
ERROR: function crosstab(unknown) does not exist** 

¿Hay alguna manera elegante de hacerlo en PostgreSQL (ninguna función integrada ...) ¿Cuál es la práctica habitual de haciéndolo ?

Respuesta

5

Esto se puede expresar como una combinación:

SELECT c.colorname, c.hexa, r.rgbvalue, g.rgbvalue, b.rgbvalue 
FROM (SELECT colorname, hexa 
     FROM sometable 
     GROUP BY colorname) c 
JOIN sometable r ON c.colorname = r.colorname AND r.rgb = 'r' 
JOIN sometable g ON c.colorname = g.colorname AND g.rgb = 'g' 
JOIN sometable b ON c.colorname = b.colorname AND b.rgb = 'b' 
; 
+0

Pero por qué tabla de referencias cruzadas didnot trabajo ... ¿no se apoyan en la versión actual que estoy usando? –

+4

'crosstab()' pertenece al módulo 'tablefunc'. Tendrás que habilitarlo usando 'CREATE EXTENSION'. Eso dicho; la comodidad que ofrece puede no ser tan buena; postgresql es fantásticamente bueno para optimizar uniones, y este tipo de código será más reconocible en más bases de datos y para más desarrolladores. – SingleNegationElimination

+0

Si haces MUCHA tabla cruzada, el módulo contrib de tablefunc puede ser genial. Si está en Ubuntu, puede agregar funciones de tabla a una base de datos haciendo esto: psql nombre_bd -f/usr/share/postgresql/8.4 /contrib/tablefunc.sql o algo similar. –

32

Ejecutar este

CREATE EXTENSION tablefunc; 

y tratar de ejecutar la consulta

+2

si ejecuto esto obtengo 'ERROR: extension" tablefunc "ya existe' pero cuando trato de usarlo obtengo' ERROR: function crosstab (unknown) does exists'. Estoy usando Postgres 9.2.1 en Mac 10.9.2. ¿Algunas ideas? – Black

+2

Asegúrese de estar conectado a su base de datos con \ c db_name y luego ejecute el comando anterior. – sm0ke21

+1

Esta [respuesta] (https://stackoverflow.com/a/23073241/177116) tiene respuesta a la pregunta planteada en el comentario de @ Black. –