lunes, 26 de julio de 2010

PostgreSQL: crosstab - Filas a columnas en una consulta SQL-

Bien.. hace unos dias me preguntaron como se crea una consulta para transformar filas a columnas, muy usado para generar reportes en tus codigos PHP, pues bien, en SQL server aparentemente debes usar procedimientos almacenados, en Oracle 11g existe una funcion PIVOT, pero investigando por ahi consegui esta informacion en la misma pagina de postgres... Ver.
Normalmente para evitar programar funciones o procedimientos almacenados uno crea codigo php medianamente complejo para armar las consultas y cambiar las filas q contienen resultados o datos de filas a columnas agrupando valores para conseguir un reporte que se entienda aqui voy a explicar como se hace en Postgres 8.3 y 8.4 utilizando las librerias contrib

Primero, debes tener instalado en contrib en la maquina
# aptitude install postgresql-contrib-8.3


el contrib de postgres provee una serie de funciones muy utiles para desarrolladores y administradores (Ej. dblink) asi como tambien la funcion crosstab

para instalar la funcion en tu BD debes ser el usuario postgres en la maquina y por lineas de comando
$ cd /usr/share/postgresql/8.3/contrib
$ psql test < tablefunc.sql


Y listo.. tu bd test tiene habilitada la funcion.. si necesitas q tus otras BD tengan la funcion cargada debes hacer el procedimiento por cada BD.. ahora, si necesitas que todas tus futuras bases de datos vengan con la funcion precargada al momento de crearlas debes hacer esto:

$ cd /usr/share/postgresql/8.3/contrib
$ psql template1 < tablefunc.sql


bien, ya tenemos las funciones cargadas, pero ¿Como la usamos?...
veamos un ejemplo:
creamos una tabla de prueba con datos
CREATE TABLE ct(id SERIAL, rowid TEXT, attribute TEXT, value TEXT);
INSERT INTO ct(rowid, attribute, value) VALUES('test1','att1','val1');
INSERT INTO ct(rowid, attribute, value) VALUES('test1','att2','val2');
INSERT INTO ct(rowid, attribute, value) VALUES('test1','att3','val3');
INSERT INTO ct(rowid, attribute, value) VALUES('test1','att4','val4');
INSERT INTO ct(rowid, attribute, value) VALUES('test2','att1','val5');
INSERT INTO ct(rowid, attribute, value) VALUES('test2','att2','val6');
INSERT INTO ct(rowid, attribute, value) VALUES('test2','att3','val7');
INSERT INTO ct(rowid, attribute, value) VALUES('test2','att4','val8');


Visualizamos los datos

select * from ct

1;"test1";"att1";"val1"
2;"test1";"att2";"val2"
3;"test1";"att3";"val3"
4;"test1";"att4";"val4"
5;"test2";"att1";"val5"
6;"test2";"att2";"val6"
7;"test2";"att3";"val7"
8;"test2";"att4";"val8"



y ahora a ver la funcion en accion: queremos ver test1 y test2 con todos sus valores en la misma fila:
SELECT *
FROM crosstab(
'select rowid, attribute, value
from ct
order by rowid,attribute')
AS ct(row_name text, category_1 text, category_2 text, category_3 text, category_4 text);

"test1";"val1";"val2";"val3";"val4"
"test2";"val5";"val6";"val7";"val8"

Y listo..

No hay comentarios:

Publicar un comentario