Es gibt mehrere Möglichkeiten, diese Daten umzuwandeln. In Ihrem ursprünglichen Beitrag haben Sie angegeben, dass PIVOT
erscheint für dieses Szenario zu komplex, lässt sich aber sehr einfach sowohl mit dem UNPIVOT
anwenden und PIVOT
Funktionen in SQL Server.
Wenn Sie jedoch keinen Zugriff auf diese Funktionen haben, kann dies mit UNION ALL
repliziert werden zu UNPIVOT
und dann eine Aggregatfunktion mit einem CASE
-Anweisung an 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, Gesamt- 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
Die UNION ALL
führt das UNPIVOT
durch der Daten durch Transformieren der Spalten Paul, John, Tim, Eric
in getrennte Reihen. Dann wenden Sie die Aggregatfunktion sum()
an mit dem case
-Anweisung, um die neuen Spalten für jede color
zu erhalten .
Unpivot- und Pivot-Static-Version:
Sowohl das UNPIVOT
und PIVOT
Funktionen in SQL Server machen diese Transformation viel einfacher. Wenn Sie alle Werte kennen, die Sie transformieren möchten, können Sie sie in eine statische Version hartcodieren, 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 UNPIVOT
erfüllt dieselbe Funktion wie UNION ALL
. Es nimmt die Liste der Spalten und wandelt sie in Zeilen um, den PIVOT
führt dann die endgültige Umwandlung in Spalten durch.
Dynamische Pivot-Version:
Wenn Sie eine unbekannte Anzahl von Spalten haben (Paul, John, Tim, Eric
in Ihrem Beispiel) und dann eine unbekannte Anzahl von Farben zu transformieren, können Sie dynamisches SQL verwenden, um die Liste für UNPIVOT
zu generieren 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, '[email protected]+'
from
(
select color, name, value
from yourtable
unpivot
(
value for name in ('[email protected]+')
) unpiv
) src
pivot
(
sum(value)
for color in ('[email protected]+')
) piv'
exec(@query)
Siehe SQL Fiddle mit Demo
Die dynamische Version fragt sowohl yourtable
und dann die sys.columns
Tabelle, um die Liste der Elemente für UNPIVOT
zu generieren und PIVOT
. Dies wird dann zu einer auszuführenden Abfragezeichenfolge hinzugefügt. Der Vorteil der dynamischen Version ist, wenn Sie eine sich ändernde Liste von colors
haben und/oder names
dies erzeugt die Liste zur Laufzeit.
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 |