Es gibt verschiedene Möglichkeiten, diese Daten zu transformieren. In Ihrem ursprünglichen Beitrag haben Sie angegeben, dass PIVOTdies für dieses Szenario zu komplex erscheint, es jedoch sehr einfach mit den Funktionen UNPIVOTundPIVOT in SQL Server angewendet werden kann .
Wenn Sie jedoch keinen Zugriff auf diese Funktionen haben, kann dies mithilfe von UNION ALLto UNPIVOTund anschließend einer Aggregatfunktion mit der CASEAnweisung to repliziert werden PIVOT:
Tabelle erstellen:
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);
Union All, Aggregate und CASE Version:
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
Siehe SQL Fiddle mit Demo
Das UNION ALLführt die UNPIVOTDaten aus, indem die Spalten Paul, John, Tim, Ericin separate Zeilen umgewandelt werden. Anschließend wenden Sie die Aggregatfunktion sum()mit der caseAnweisung an, um die neuen Spalten für jede zu erhalten color.
Unpivot und Pivot Static Version:
Sowohl die UNPIVOTals auch die PIVOTFunktionen in SQL Server erleichtern diese Umwandlung erheblich. Wenn Sie alle Werte kennen, die Sie transformieren möchten, können Sie sie in eine statische Version fest codieren, um das Ergebnis zu erhalten:
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
Siehe SQL Fiddle mit Demo
Die innere Abfrage mit dem hat UNPIVOTdie gleiche Funktion wie die UNION ALL. Es nimmt die Liste der Spalten und PIVOTwandelt sie in Zeilen um. Anschließend führt es die endgültige Umwandlung in Spalten durch.
Dynamische Pivot-Version:
Wenn Sie eine unbekannte Anzahl von Spalten ( Paul, John, Tim, Ericin Ihrem Beispiel) und dann eine unbekannte Anzahl von zu transformierenden Farben haben, können Sie die Liste mit dynamischem SQL generieren UNPIVOTund dann 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)
Siehe SQL Fiddle mit Demo
Die dynamische Version fragt sowohl yourtabledie sys.columnsTabelle als auch die Tabelle ab, um die Liste der Elemente für UNPIVOTund zu generieren PIVOT. Dies wird dann zu einer auszuführenden Abfragezeichenfolge hinzugefügt. Das Plus der dynamischen Version ist, wenn Sie eine sich ändernde Liste von haben colorsund / oder namesdie Liste zur Laufzeit generiert wird.
Alle drei Abfragen führen zum gleichen Ergebnis:
| NAME | RED | GREEN | BLUE |
-----------------------------
| Eric | 3 | 5 | 1 |
| John | 5 | 4 | 2 |
| Paul | 1 | 8 | 2 |
| Tim | 1 | 3 | 9 |