Es gibt verschiedene Möglichkeiten, diese Daten zu transformieren. In Ihrem ursprünglichen Beitrag haben Sie angegeben, dass PIVOT
dies für dieses Szenario zu komplex erscheint, es jedoch sehr einfach mit den Funktionen UNPIVOT
undPIVOT
in SQL Server angewendet werden kann .
Wenn Sie jedoch keinen Zugriff auf diese Funktionen haben, kann dies mithilfe von UNION ALL
to UNPIVOT
und anschließend einer Aggregatfunktion mit der CASE
Anweisung 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 ALL
führt die UNPIVOT
Daten aus, indem die Spalten Paul, John, Tim, Eric
in separate Zeilen umgewandelt werden. Anschließend wenden Sie die Aggregatfunktion sum()
mit der case
Anweisung an, um die neuen Spalten für jede zu erhalten color
.
Unpivot und Pivot Static Version:
Sowohl die UNPIVOT
als auch die PIVOT
Funktionen 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 UNPIVOT
die gleiche Funktion wie die UNION ALL
. Es nimmt die Liste der Spalten und PIVOT
wandelt 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, Eric
in Ihrem Beispiel) und dann eine unbekannte Anzahl von zu transformierenden Farben haben, können Sie die Liste mit dynamischem SQL generieren UNPIVOT
und 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 yourtable
die sys.columns
Tabelle als auch die Tabelle ab, um die Liste der Elemente für UNPIVOT
und 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 colors
und / oder names
die 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 |