Існує кілька способів перетворення цих даних. У своєму початковому дописі ви заявили, що PIVOTздається занадто складним для цього сценарію, але його можна застосувати дуже легко, використовуючи UNPIVOTіPIVOT функції, і функції SQL Server.
Однак, якщо у вас немає доступу до цих функцій , це може бути відтворено з допомогою UNION ALLдо 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, агрегат та 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 with Demo
У 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 with Demo
Внутрішній запит UNPIVOTвиконує ту саму функцію, що і UNION ALL. Він бере список стовпців і перетворює їх у рядки, 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 with Demo
Динамічна версія запитує і те, 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 |