9 abr 2009

// // 2 comentarios

PIVOT SQL: Pasar filas a columnas

SQL no es mi fuerte, pero quisiera compartirles algo que he usado últimamente para solucionar un problema que he tenido con una consulta, pues resulta que tengo una tabla de Productos, los cuales están clasificados (Línea-Representada), lo cual lo tenia en otras tablas, y necesitaba traer cada producto con su línea y representada, con una consulta normal como esta:

SELECT    P.Codigo, P.Nombre, N.Nombre AS Nivel, A.Nombre AS Atributo, P.Ean
FROM Productos P
INNER JOIN ProductoAtributos PA ON PA.ProductoID = P.ProductoID
INNER JOIN Atributos A ON A.AtributoID = PA.AtributoID
INNER JOIN NivelProducto N ON N .NivelID = A.NivelID


El resultado seria el siguiente:



Codigo      Nombre                       Nivel                 Atributo                Ean             
-----------   ------------------------     --------------        -----------               ---------------


1000000     PAMPERS BABYSEC     Línea                 LACTEOS               5655425689322


1000000     PAMPERS BABYSEC     Representada    GLORIA                 5655425689322


1000001     GASEOSA CASINELLI   Línea                 CONDIMENTOS      6547574575474


1000001     GASEOSA CASINELLI   Representada    AJINOMOTO          6547574575474



Si analizamos el resultado, no nos sirve de mucho ya que se repite el producto con la Línea y la Representada, a mi lo que me interesa es tener la Línea y la representada en un solo registro con el producto, así que revisando un poco encontré la solución en PIVOT, esta es una característica nueva que viene a partir de la versión 2005 de SQL.



Con esta característica podremos colocar la Línea y la Representada en columnas y obtener el resultado deseado, la consulta quedaría algo así:



SELECT Codigo, Nombre, [Linea] AS 'Linea', [Representada] AS 'Representada', Ean
FROM (
SELECT P.Codigo, P.Nombre, N.Nombre AS Nivel, A.Nombre AS Atributo, P.Ean
FROM Productos P
INNER JOIN ProductoAtributos PA ON PA.ProductoID = P.ProductoID
INNER JOIN Atributos A ON A.AtributoID = PA.AtributoID
INNER JOIN NivelProducto N ON N .NivelID = A.NivelID
) PVT
PIVOT(
MIN(Atributo) FOR [Nivel] IN([Linea], [Representada])) AS Child




Obteniendo el resultado siguiente



 



Codigo      Nombre                       Línea                Representada   Ean

-----------   -------------------           ------------          -------------         ---------------


1000000     PAMPERS BABYSEC     LACTEOS           GLORIA             5655425689322


1000001     GASEOSA CASINELLI   CONDIMENTOS  AJINOMOTO      6547574575474



Esto si que nos sirve, tenemos un resultado mas ordenado y mejor presentado, con esto solucionamos el problema, esto se le conoce como PIVOT Estático, ya que las columnas las asignamos en duro, pero también se puede hacer dinámicamente, quizá mas adelante comente al respecto, por mientras les dejo algunos enlaces para que puedan profundizar el tema.



Usar PIVOT y UNPIVOT



Pasar filas a columnas con T-SQL: PIVOT() y las cosas que te alegran el día :)



Pivot y Unpivot en SQL Server 2005



Implementación de PIVOT Dinámico

2 comentarios:

Anónimo dijo...

Excelente Publicación

spakinz dijo...

Estaba buscando un ejemplo sencillo de PIVOT y este encaja perfectamente con lo que necesitaba. Gracias Ricardo.