Det finns flera sätt att omvandla denna data. I ditt ursprungliga inlägg angav du att PIVOT verkar för komplicerat för detta scenario, men det kan appliceras mycket enkelt med både UNPIVOT och PIVOT funktioner i SQL Server.
Men om du inte har tillgång till dessa funktioner kan detta replikeras med UNION ALL till UNPIVOT och sedan en aggregerad funktion med en CASE uttalande till PIVOT :
Skapa tabell:
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 och 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
Se SQL Fiddle with Demo
UNION ALL utför UNPIVOT av data genom att transformera kolumnerna Paul, John, Tim, Eric i separata rader. Sedan tillämpar du aggregatfunktionen sum() med case för att få de nya kolumnerna för varje color .
Unpivot och Pivot Static Version:
Både UNPIVOT och PIVOT funktioner i SQL server gör denna transformation mycket enklare. Om du känner till alla värden som du vill omvandla kan du hårdkoda dem till en statisk version för att få resultatet:
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
Se SQL Fiddle with Demo
Den inre frågan med UNPIVOT utför samma funktion som UNION ALL . Den tar listan med kolumner och gör om den till rader, PIVOT utför sedan den slutliga omvandlingen till kolumner.
Dynamisk pivotversion:
Om du har ett okänt antal kolumner (Paul, John, Tim, Eric i ditt exempel) och sedan ett okänt antal färger att transformera kan du använda dynamisk sql för att generera listan till UNPIVOT och sedan 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)
Se SQL Fiddle with Demo
Den dynamiska versionen frågar både yourtable och sedan sys.columns tabell för att generera listan över objekt till UNPIVOT och PIVOT . Detta läggs sedan till i en frågesträng som ska köras. Plusen med den dynamiska versionen är om du har en föränderlig lista med colors och/eller names detta genererar listan vid körning.
Alla tre frågorna ger samma resultat:
| NAME | RED | GREEN | BLUE |
-----------------------------
| Eric | 3 | 5 | 1 |
| John | 5 | 4 | 2 |
| Paul | 1 | 8 | 2 |
| Tim | 1 | 3 | 9 |