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 điều đó PIVOTcó vẻ quá phức tạp đối với tình huống này, nhưng nó có thể được áp dụng rất dễ dàng bằng cách sử dụng cả hàm UNPIVOTvàPIVOT trong SQL Server.
Tuy nhiên, nếu bạn không có quyền truy cập vào các hàm đó, điều này có thể được sao chép bằng cách sử dụng UNION ALLtới UNPIVOTvà sau đó là một hàm tổng hợp với CASEcâu lệnh 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
Thực UNION ALLhiện UNPIVOTdữ liệu bằng cách chuyển các cột Paul, John, Tim, Ericthành các hàng riêng biệt. Sau đó, bạn áp dụng hàm tổng hợp sum()với casecâu lệnh để lấy các cột mới cho mỗi color.
Unpivot và Pivot phiên bản tĩnh:
Cả hàm UNPIVOTvà PIVOThàm trong máy chủ SQL đều 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 hàm UNPIVOTthự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, PIVOTsau đó thực hiện chuyển đổi cuối cùng thành các cột.
Phiên bản Pivot động:
Nếu bạn có một số lượng cột không xác định ( Paul, John, Tim, Erictrong ví dụ của bạn) và sau đó 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 UNPIVOTvà sau đó 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)
Xem SQL Fiddle với Demo
Phiên bản động truy vấn cả hai yourtablevà sau đó truy vấn sys.columnsbảng để tạo danh sách các mục đến UNPIVOTvà 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 thay đổi colorsvà / hoặc namesdanh sách này sẽ tạo danh sách tại thời điểm chạy.
Cả ba truy vấn sẽ tạo 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 |