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, '[email protected]+'
from
(
select color, name, value
from yourtable
unpivot
(
value for name in ('[email protected]+')
) unpiv
) src
pivot
(
sum(value)
for color in ('[email protected]+')
) 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 |