Existem várias maneiras de transformar esses dados. Em sua postagem original, você afirmou que PIVOTparece muito complexo para este cenário, mas pode ser aplicado facilmente usando o UNPIVOTePIVOT funções do SQL Server.
No entanto, se você não tiver acesso a essas funções, isso pode ser replicado usando UNION ALLpara UNPIVOTe, em seguida, uma função agregada com uma CASEinstrução paraPIVOT :
Criar a tabela:
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);
Versão de união de todos, agregado e 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
Vejo SQL Fiddle com Demo
O UNION ALLexecuta a eliminação UNPIVOTdos dados transformando as colunas Paul, John, Tim, Ericem linhas separadas. Em seguida, você aplica a função de agregação sum()com a caseinstrução para obter as novas colunas para cadacolor .
Versão Estática Unpivot e Pivot:
As funções UNPIVOTe PIVOTno servidor SQL tornam essa transformação muito mais fácil. Se você conhece todos os valores que deseja transformar, pode codificá-los em uma versão estática para obter o resultado:
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
Vejo SQL Fiddle com Demo
A consulta interna com UNPIVOTexecuta a mesma função que UNION ALL. Ele pega a lista de colunas e a transforma em linhas, oPIVOT então realiza a transformação final em colunas.
Versão dinâmica do pivô:
Se você tiver um número desconhecido de colunas ( Paul, John, Tim, Ericem seu exemplo) e, em seguida, um número desconhecido de cores para transformar, você pode usar sql dinâmico para gerar a lista para UNPIVOTe então 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)
Vejo SQL Fiddle com Demo
A versão dinâmica consulta ambos yourtablee a sys.columnstabela para gerar a lista de itens para UNPIVOTe PIVOT. Isso é então adicionado a uma string de consulta a ser executada. A vantagem da versão dinâmica é se você tem uma lista de alteração de colorse / ou namesisso irá gerar a lista em tempo de execução.
Todas as três consultas produzirão o mesmo resultado:
| NAME | RED | GREEN | BLUE |
-----------------------------
| Eric | 3 | 5 | 1 |
| John | 5 | 4 | 2 |
| Paul | 1 | 8 | 2 |
| Tim | 1 | 3 | 9 |