Hay varias formas de transformar estos datos. En su publicación original, dijo que PIVOTparece demasiado complejo para este escenario, pero se puede aplicar muy fácilmente usando las funciones UNPIVOTyPIVOT en SQL Server.
Sin embargo, si usted no tiene acceso a estas funciones se pueden replicar esta usando UNION ALLa UNPIVOTy luego una función de agregado con una CASEdeclaración a PIVOT:
Crear mesa:
CREATE TABLE yourTable([color] varchar(5), [Paul] int, [John] int, [Tim] int, [Eric] int);
INSERT INTO yourTable
([color], [Paul], [John], [Tim], [Eric])
VALUES
('Red', 1, 5, 1, 3),
('Green', 8, 4, 3, 5),
('Blue', 2, 2, 9, 1);
Versión Union All, Agregada y CASE:
select name,
sum(case when color = 'Red' then value else 0 end) Red,
sum(case when color = 'Green' then value else 0 end) Green,
sum(case when color = 'Blue' then value else 0 end) Blue
from
(
select color, Paul value, 'Paul' name
from yourTable
union all
select color, John value, 'John' name
from yourTable
union all
select color, Tim value, 'Tim' name
from yourTable
union all
select color, Eric value, 'Eric' name
from yourTable
) src
group by name
Ver SQL Fiddle con demostración
Los UNION ALLrealiza las UNPIVOTde los datos mediante la transformación de las columnas Paul, John, Tim, Ericen filas separadas. Luego aplica la función agregada sum()con la casedeclaración para obtener las nuevas columnas para cada una color.
Versión estática sin pivote y pivote:
Tanto las funciones UNPIVOTy PIVOTen el servidor SQL facilitan mucho esta transformación. Si conoce todos los valores que desea transformar, puede codificarlos en una versión estática para obtener el resultado:
select name, [Red], [Green], [Blue]
from
(
select color, name, value
from yourtable
unpivot
(
value for name in (Paul, John, Tim, Eric)
) unpiv
) src
pivot
(
sum(value)
for color in ([Red], [Green], [Blue])
) piv
Ver SQL Fiddle con demostración
La consulta interna con UNPIVOTrealiza la misma función que UNION ALL. Toma la lista de columnas y la convierte en filas, PIVOTluego realiza la transformación final en columnas.
Versión dinámica de pivote:
Si tiene un número desconocido de columnas ( Paul, John, Tim, Ericen su ejemplo) y luego un número desconocido de colores para transformar, puede usar sql dinámico para generar la lista UNPIVOTy luego PIVOT:
DECLARE @colsUnpivot AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX),
@colsPivot as NVARCHAR(MAX)
select @colsUnpivot = stuff((select ','+quotename(C.name)
from sys.columns as C
where C.object_id = object_id('yourtable') and
C.name <> 'color'
for xml path('')), 1, 1, '')
select @colsPivot = STUFF((SELECT ','
+ quotename(color)
from yourtable t
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query
= 'select name, '+@colsPivot+'
from
(
select color, name, value
from yourtable
unpivot
(
value for name in ('+@colsUnpivot+')
) unpiv
) src
pivot
(
sum(value)
for color in ('+@colsPivot+')
) piv'
exec(@query)
Ver SQL Fiddle con demostración
La versión dinámica consulta ambos yourtabley luego la sys.columnstabla para generar la lista de elementos para UNPIVOTy PIVOT. Esto luego se agrega a una cadena de consulta para su ejecución. La ventaja de la versión dinámica es si tiene una lista cambiante colorsy / o namesesto generará la lista en tiempo de ejecución.
Las tres consultas producirán el mismo resultado:
| NAME | RED | GREEN | BLUE |
-----------------------------
| Eric | 3 | 5 | 1 |
| John | 5 | 4 | 2 |
| Paul | 1 | 8 | 2 |
| Tim | 1 | 3 | 9 |