Điều này sẽ hoạt động:
WITH Sales AS (
SELECT
S.SaleID,
S.SoldBy,
S.SalePrice,
S.Margin,
S.Date,
I.SalePrice,
I.Category
FROM
dbo.Sale S
INNER JOIN dbo.SaleItem I
ON S.SaleID = I.SaleID
)
SELECT *
FROM
Sales
PIVOT (Max(SalePrice) FOR Category IN (Books, Printing, DVD)) P
;
Hoặc luân phiên:
SELECT
S.SaleID,
S.SoldBy,
S.SalePrice,
S.Margin,
S.Date,
I.Books,
I.Printing,
I.DVD
FROM
dbo.Sale S
INNER JOIN (
SELECT *
FROM
(SELECT SaleID, SalePrice, Category FROM dbo.SaleItem) I
PIVOT (Max(SalePrice) FOR Category IN (Books, Printing, DVD)) P
) I ON S.SaleID = I.SaleID
;
Các kết quả này có cùng tập hợp kết quả và trên thực tế có thể được trình tối ưu hóa truy vấn xử lý giống nhau, nhưng có thể không. Sự khác biệt lớn có tác dụng khi bạn bắt đầu đặt các điều kiện cho Sale
bảng — bạn nên kiểm tra và xem truy vấn nào hoạt động tốt hơn.
Lưu ý:điều quan trọng khi sử dụng PIVOT
rằng chỉ các cột phải là một phần của kết quả đầu ra mới có sẵn. Đây là lý do tại sao hai truy vấn trên có thêm truy vấn phụ trong bảng dẫn xuất (SELECT ...)
để chỉ các cột cụ thể được hiển thị. Tất cả các cột có sẵn để xem bởi PIVOT
không được liệt kê trong biểu thức xoay sẽ được nhóm ngầm và đưa vào kết quả cuối cùng. Đây có thể sẽ không phải là điều bạn muốn.
Tuy nhiên, tôi có thể đề nghị bạn thực hiện xoay vòng trong lớp trình bày không? Ví dụ, nếu bạn đang sử dụng SSRS, thì khá dễ dàng để sử dụng một điều khiển ma trận sẽ thực hiện tất cả việc xoay vòng cho bạn. Điều đó là tốt nhất, vì sau đó nếu bạn thêm một Category
mới , bạn sẽ không phải sửa đổi tất cả mã SQL của mình!
Có một cách để tự động tìm tên cột để xoay vòng, nhưng nó liên quan đến SQL động. Tôi cũng không thực sự khuyên đó là cách tốt nhất, mặc dù điều đó là có thể.
Một cách khác mà có thể công việc sẽ là xử lý trước truy vấn này — nghĩa là đặt một trình kích hoạt trên Category
bảng ghi lại một dạng xem để chứa tất cả các danh mục hiện có tồn tại. Điều này giải quyết được rất nhiều vấn đề khác mà tôi đã đề cập, nhưng một lần nữa, sử dụng lớp trình bày là tốt nhất.
Lưu ý :Nếu tên cột của bạn (trước đây là giá trị) có khoảng trắng, là số hoặc bắt đầu bằng số hoặc không phải là số nhận dạng hợp lệ, bạn phải trích dẫn chúng bằng dấu ngoặc vuông như trong PIVOT (Max(Value) FOR CategoryId IN ([1], [2], [3], [4])) P
. Ngoài ra, bạn có thể sửa đổi các giá trị trước khi chúng đến PIVOT
một phần của truy vấn để thêm vào trước một số chữ cái hoặc xóa khoảng trắng để danh sách cột không cần phải thoát. Để đọc thêm về điều này, hãy xem các quy tắc cho số nhận dạng trong SQL Server.