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 đó PIVOT
có 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 UNPIVOT
và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 ALL
tới UNPIVOT
và sau đó là một hàm tổng hợp với CASE
câ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 ALL
hiện UNPIVOT
dữ liệu bằng cách chuyển 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 để lấy các cột mới cho mỗi color
.
Unpivot và Pivot phiên bản tĩnh:
Cả hàm UNPIVOT
và PIVOT
hà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 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 Pivot động:
Nếu bạn có một số lượng cột không xác định ( Paul, John, Tim, Eric
trong 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 UNPIVOT
và 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 yourtable
và sau đó truy vấn sys.columns
bảng để tạo danh sách các mục đến 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 thay đổi colors
và / hoặc names
danh 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 |