Існує кілька способів перетворення цих даних. У своєму початковому дописі ви заявили, що 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 |