Có một số cách mà bạn có thể chuyển đổi dữ liệu này. Trong bài đăng ban đầu của mình, bạn đã nói rằng PIVOT có vẻ quá phức tạp đối với trường hợp này, nhưng nó có thể được áp dụng rất dễ dàng bằng cách sử dụng cả UNPIVOT và PIVOT các chức năng trong SQL Server.
Tuy nhiên, nếu bạn không có quyền truy cập vào các chức năng đó, điều này có thể được sao chép bằng cách sử dụng UNION ALL thành UNPIVOT và sau đó là một hàm tổng hợp với CASE câu lệnh cho PIVOT :
Tạo bảng:
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);
Kết hợp tất cả, tổng hợp và phiên bản 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
Xem SQL Fiddle với Demo
UNION ALL thực hiện UNPIVOT của dữ liệu bằng cách chuyển đổi các cột Paul, John, Tim, Eric thành các hàng riêng biệt. Sau đó, bạn áp dụng hàm tổng hợp sum() với case câu lệnh để nhận các cột mới cho mỗi color .
Unpivot và Pivot phiên bản tĩnh:
Cả UNPIVOT và PIVOT các hàm trong máy chủ SQL làm cho việc chuyển đổi này trở nên dễ dàng hơn nhiều. Nếu bạn biết tất cả các giá trị mà bạn muốn chuyển đổi, bạn có thể mã hóa chúng thành một phiên bản tĩnh để nhận được kết quả:
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
Xem SQL Fiddle với Demo
Truy vấn bên trong với UNPIVOT thực hiện chức năng tương tự như UNION ALL . Nó lấy danh sách các cột và biến nó thành các hàng, PIVOT sau đó thực hiện chuyển đổi cuối cùng thành các cột.
Phiên bản tổng hợp động:
Nếu bạn có số lượng cột không xác định (Paul, John, Tim, Eric trong ví dụ của bạn) và sau đó là một số lượng màu không xác định để chuyển đổi, bạn có thể sử dụng sql động để tạo danh sách thành UNPIVOT rồi đến 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)
Xem SQL Fiddle với Demo
Phiên bản động truy vấn cả yourtable và sau đó là sys.columns bảng để tạo danh sách các mục cho UNPIVOT và PIVOT . Điều này sau đó được thêm vào một chuỗi truy vấn để được thực thi. Điểm cộng của phiên bản động là nếu bạn có danh sách color đang thay đổi và / hoặc names điều này sẽ tạo danh sách tại thời điểm chạy.
Cả ba truy vấn sẽ cho ra cùng một kết quả:
| NAME | RED | GREEN | BLUE |
-----------------------------
| Eric | 3 | 5 | 1 |
| John | 5 | 4 | 2 |
| Paul | 1 | 8 | 2 |
| Tim | 1 | 3 | 9 |