Esistono diversi modi per trasformare questi dati. Nel tuo post originale, hai affermato che PIVOTsembra troppo complesso per questo scenario, ma può essere applicato molto facilmente utilizzando sia il UNPIVOTchePIVOT funzioni in SQL Server.
Tuttavia, se non si ha accesso a tali funzioni, è possibile replicarlo utilizzando UNION ALLa UNPIVOTe quindi una funzione di aggregazione con CASEun'istruzione a PIVOT:
Crea tabella:
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);
Versione Union All, Aggregate e 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
Vedi SQL Fiddle con Demo
Il UNION ALLesegue il UNPIVOTdei dati trasformando le colonne Paul, John, Tim, Ericin righe separate. Quindi si applica la funzione di aggregazione sum()con l' caseistruzione per ottenere le nuove colonne per ciascuna color.
Versione statica unpivot e pivot:
Sia l' UNPIVOTe PIVOTfunzioni in SQL Server rendono questa trasformazione molto più facile. Se conosci tutti i valori che vuoi trasformare, puoi codificarli come hardcoded in una versione statica per ottenere il risultato:
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
Vedi SQL Fiddle con Demo
La query interna con UNPIVOTesegue la stessa funzione di UNION ALL. Prende l'elenco delle colonne e lo trasforma in righe, PIVOTquindi esegue la trasformazione finale in colonne.
Versione pivot dinamica:
Se hai un numero sconosciuto di colonne ( Paul, John, Tim, Ericnel tuo esempio) e quindi un numero sconosciuto di colori da trasformare, puoi utilizzare sql dinamico per generare l'elenco UNPIVOTe quindi 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)
Vedi SQL Fiddle con Demo
La versione dinamica interroga entrambi yourtablee quindi la sys.columnstabella per generare l'elenco di elementi in UNPIVOTe PIVOT. Questo viene quindi aggiunto a una stringa di query da eseguire. Il vantaggio della versione dinamica è se si dispone di un elenco di modifiche colorse / o namesquesto genererà l'elenco in fase di esecuzione.
Tutte e tre le query produrranno lo stesso risultato:
| NAME | RED | GREEN | BLUE |
-----------------------------
| Eric | 3 | 5 | 1 |
| John | 5 | 4 | 2 |
| Paul | 1 | 8 | 2 |
| Tim | 1 | 3 | 9 |