Эти данные можно преобразовать несколькими способами. В исходном сообщении, вы заявили , что PIVOT
кажется слишком сложным для этого сценария, но он может быть применен очень легко , используя как UNPIVOT
иPIVOT
функцию в SQL Server.
Однако, если у вас нет доступа к этим функциям, их можно воспроизвести с помощью функции UNION ALL
to, UNPIVOT
а затем агрегатной функции с CASE
инструкцией для PIVOT
:
Создать таблицу:
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 и 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
См. SQL Fiddle с демонстрацией
В UNION ALL
выполн ет UNPIVOT
из данных путем преобразования столбцов Paul, John, Tim, Eric
в отдельные строки. Затем вы применяете агрегатную функциюsum()
с case
оператором, чтобы получить новые столбцы для каждого color
.
Статическая версия Unpivot и Pivot:
Оба UNPIVOT
иPIVOT
функция в сервере SQL сделать это преобразование гораздо проще. Если вы знаете все значения, которые хотите преобразовать, вы можете жестко закодировать их в статическую версию, чтобы получить результат:
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
Видеть SQL Fiddle с демонстрацией
Внутренний запрос с UNPIVOT
классом выполняет ту же функцию, что и UNION ALL
. Он берет список столбцов и превращает его в строки,PIVOT
затем выполняет окончательное преобразование в столбцы.
Версия Dynamic Pivot:
Если у вас есть неизвестное количество столбцов ( Paul, John, Tim, Eric
в вашем примере), а затем неизвестное количество цветов для преобразования, вы можете использовать динамический sql для создания списка, UNPIVOT
а затем 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)
Видеть SQL Fiddle с демонстрацией
Динамическая версия запрашивает обе, yourtable
а затем sys.columns
таблицу для создания списка элементов для UNPIVOT
и PIVOT
. Затем он добавляется в строку запроса для выполнения. Плюс динамической версии в том, что у вас есть изменяющийся списокcolors
и / или names
он будет генерировать список во время выполнения.
Все три запроса дадут одинаковый результат:
| NAME | RED | GREEN | BLUE |
-----------------------------
| Eric | 3 | 5 | 1 |
| John | 5 | 4 | 2 |
| Paul | 1 | 8 | 2 |
| Tim | 1 | 3 | 9 |