Bạn cần biết tất cả các giá trị có thể để PIVOT bằng. Vì vậy, rất khó để thực hiện điều này trực tiếp với T-SQL trừ khi bạn sử dụng SQL động và điều này có thể trở nên khá nhanh chóng. Có lẽ tốt hơn nên chuyển tất cả các hàng trở lại tầng trình bày hoặc người viết báo cáo và để nó xoay chúng sang một bên.
Đây là một ví dụ PIVOT nhanh nếu bạn biết trước tất cả các giá trị của UBCategory. Tôi đã bỏ ICCUDays vì nó có vẻ không liên quan trừ khi có các cột xuất phát từ chế độ xem đó như một phần của kết quả.
USE tempdb;
GO
SET NOCOUNT ON;
GO
-- who on earth is responsible for your naming scheme?
CREATE TABLE dbo.ICCUEnctrSelectedRevCatsDirCost
(
Account INT,
UBCategory VARCHAR(10),
DirectCost DECIMAL(9,2)
);
INSERT dbo.ICCUEnctrSelectedRevCatsDirCost
SELECT 1, 'foo', 5.25
UNION SELECT 1, 'bar', 6.25
UNION SELECT 1, 'smudge', 8.50
UNION SELECT 2, 'foo', 9.25
UNION SELECT 2, 'brap', 2.75;
SELECT Account,[foo],[bar],[smudge],[brap] FROM
dbo.ICCUEnctrSelectedRevCatsDirCost
-- WHERE <something>, I assume ???
PIVOT
(
MAX(DirectCost)
FOR UBCategory IN ([foo],[bar],[smudge],[brap])
) AS p;
GO
DROP TABLE dbo.ICCUEnctrSelectedRevCatsDirCost;
Để làm cho điều này năng động hơn, bạn phải nhận được danh sách các giá trị DISTINCT UBCategory được phân tách bằng dấu phẩy và tạo trục xoay một cách nhanh chóng. Vì vậy, nó có thể trông như thế này:
USE tempdb;
GO
SET NOCOUNT ON;
GO
-- who on earth is responsible for your naming scheme?
CREATE TABLE dbo.ICCUEnctrSelectedRevCatsDirCost
(
Account INT,
UBCategory VARCHAR(10),
DirectCost DECIMAL(9,2)
);
INSERT dbo.ICCUEnctrSelectedRevCatsDirCost
SELECT 1, 'foo', 5.25
UNION SELECT 1, 'bar', 6.25
UNION SELECT 1, 'smudge', 8.50
UNION SELECT 2, 'foo', 9.25
UNION SELECT 2, 'brap', 2.75
UNION SELECT 3, 'bingo', 4.00;
DECLARE @sql NVARCHAR(MAX),
@col NVARCHAR(MAX);
SELECT @col = COALESCE(@col, '') + QUOTENAME(UBCategory) + ','
FROM
(
SELECT DISTINCT UBCategory
FROM dbo.ICCUEnctrSelectedRevCatsDirCost
) AS x;
SET @col = LEFT(@col, LEN(@col)-1);
SET @sql = N'SELECT Account, $col$ FROM
dbo.ICCUEnctrSelectedRevCatsDirCost
-- WHERE <something>, I assume ???
PIVOT
(
MAX(DirectCost)
FOR UBCategory IN ($col$)
) AS p;';
SET @sql = REPLACE(@sql, '$col$', @col);
--EXEC sp_executeSQL @sql;
PRINT @sql;
GO
DROP TABLE dbo.ICCUEnctrSelectedRevCatsDirCost;
Sau đó, để "gửi dữ liệu đến một bảng mới", bạn có thể chỉ cần đặt truy vấn là CHÈN VÀO ... CHỌN thay vì CHỌN thẳng. Tất nhiên, điều này có vẻ vô ích, bởi vì để viết câu lệnh chèn đó, bạn cần biết thứ tự của các cột (điều này không được đảm bảo với cách tiếp cận này) và bạn cần phải đặt sẵn các cột cho mỗi UBCategory tiềm năng dù sao cũng có giá trị, vì vậy điều này có vẻ rất giống gà và trứng.