Istnieje kilka sposobów przekształcania tych danych. W oryginalnym poście stwierdziłeś, że PIVOT wydaje się zbyt skomplikowany dla tego scenariusza, ale można go bardzo łatwo zastosować za pomocą zarówno UNPIVOT i PIVOT funkcje w SQL Server.
Jeśli jednak nie masz dostępu do tych funkcji, można je zreplikować za pomocą UNION ALL do UNPIVOT a następnie funkcję agregującą z CASE oświadczenie do PIVOT :
Utwórz tabelę:
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);
Wersja Union All, Aggregate i 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
Zobacz SQL Fiddle z demonstracją
UNION ALL wykonuje UNPIVOT danych poprzez przekształcenie kolumn Paul, John, Tim, Eric w osobne rzędy. Następnie stosujesz funkcję agregującą sum() z case oświadczenie, aby uzyskać nowe kolumny dla każdego color .
Wersje statyczne Unpivot i Pivot:
Zarówno UNPIVOT i PIVOT funkcje w serwerze SQL znacznie ułatwiają tę transformację. Jeśli znasz wszystkie wartości, które chcesz przekształcić, możesz je na stałe zakodować w wersji statycznej, aby uzyskać wynik:
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
Zobacz SQL Fiddle z demonstracją
Zapytanie wewnętrzne z UNPIVOT wykonuje tę samą funkcję co UNION ALL . Pobiera listę kolumn i zamienia ją w wiersze, PIVOT następnie wykonuje ostateczną transformację w kolumny.
Dynamiczna wersja obrotowa:
Jeśli masz nieznaną liczbę kolumn (Paul, John, Tim, Eric w twoim przykładzie), a następnie nieznaną liczbę kolorów do przekształcenia, możesz użyć dynamicznego sql, aby wygenerować listę do UNPIVOT a następnie 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, 'example@sqldat.com+'
from
(
select color, name, value
from yourtable
unpivot
(
value for name in ('example@sqldat.com+')
) unpiv
) src
pivot
(
sum(value)
for color in ('example@sqldat.com+')
) piv'
exec(@query)
Zobacz SQL Fiddle z demonstracją
Wersja dynamiczna wysyła zapytania zarówno do yourtable a następnie sys.columns tabela do generowania listy elementów do UNPIVOT i PIVOT . Jest to następnie dodawane do ciągu zapytania do wykonania. Plusem wersji dynamicznej jest to, że masz zmieniającą się listę colors i/lub names to wygeneruje listę w czasie wykonywania.
Wszystkie trzy zapytania dadzą ten sam wynik:
| NAME | RED | GREEN | BLUE |
-----------------------------
| Eric | 3 | 5 | 1 |
| John | 5 | 4 | 2 |
| Paul | 1 | 8 | 2 |
| Tim | 1 | 3 | 9 |