2013-06-12 31 views
19

Tôi có hai bảng với dữ liệuSQL server tham gia bảng và trục

BẢNG 1

--------------------------------------------------- 
    | SALEID | SOLDBY | SALEPRICE | MARGIN | DATE | 
    | 1  | 'aa' | 10,000 | 10 | 2013-1-1 | 
    | 2  | 'bb' | 25,000 | 5 | 2013-5-1 | 

TABLE 2

--------------------------------------------------- 
    | SALEITEMID | SALEID | SALEPRICE | CATEGORY | 
    | 1   | 1  | 6,000 | BOOKS | 
    | 2   | 1  | 4,000 | PRINTING | 
    | 3   | 2  | 5,000 | BOOKS | 
    | 4   | 2  | 12,000 | PRINTING | 
    | 5   | 2  | 8,000 | DVD  | 

Tôi cần một truy vấn mà sẽ tạo ra

tab3

-------------------------------------------------------------------------------- 
    | SALEID | SOLDBY | SALEPRICE | MARGIN | DATE | BOOKS | PRINTING | DVD 
    | 1  | 'aa' | 10,000 | 10 | 2013-1-1 | 6,000 | 4,000 | 0 
    | 2  | 'bb' | 25,000 | 5 | 2013-5-1 | 5,000 | 12,000 | 8,000 

Tôi khá mới để pivoting và không chắc chắn nếu trục là con đường để đi cho điều này hay không.

+1

Có bao nhiêu danh mục? Đây có phải là danh sách đầy đủ không? Có thể có nhiều hơn trong tương lai? – ErikE

+0

Có khoảng 7 loại. Đừng đi trên nó. –

Trả lời

35

này nên làm việc:

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 
; 

Những có resultset cùng và có thể trên thực tế được đối xử như nhau bởi tôi ưu truy vấn, nhưng có thể không. Sự khác biệt lớn xảy ra khi bạn bắt đầu đặt các điều kiện trên bảng Sale - bạn nên kiểm tra và xem truy vấn nào hoạt động tốt hơn.

Tôi có thể đề xuất bạn thực hiện xoay vòng trong lớp trình bày không? Nếu, ví dụ, bạn đang sử dụng SSRS nó là khá dễ dàng để sử dụng một điều khiển ma trận mà sẽ làm tất cả các xoay vòng cho bạn. Điều đó là tốt nhất, bởi vì sau đó nếu bạn thêm một Category mới, bạn sẽ không có sửa đổi tất cả các mã SQL của bạn!

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 không thực sự đề nghị đó là cách tốt nhất, dù là có thể.

Một cách khác mà thể công việc sẽ được xử lý trước truy vấn này - có nghĩa là để thiết lập một kích hoạt trên bàn Category mà viết lại một VIEW để chứa tất cả các hạng mục còn tồn tại mà tồn tại. Điều này giải quyết 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ị) là số hoặc bắt đầu bằng số, bạn phải báo giá 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 họ truy cập vào phần PIVOT của truy vấn để thêm một số chữ cái, để danh sách cột không cần phải thoát. Để đọc thêm về điều này, hãy kiểm tra các quy tắc cho số nhận dạng trong SQL Server.

+0

Nhờ Thật hữu ích .... Đầu tiên Query làm việc, trong truy vấn Forst Xin vui lòng thêm 'Tôi sau INNER JOIN dbo.SaleItem HOẶC INNER JOIN dbo.SaleItem tôi Cảm ơn –

+0

Hãy chắc chắn rằng bạn kiểm tra xem' Max() 'là thích hợp - nếu có thể có nhiều hơn một SaleID + Category thì có thể cần 'Sum()' hoặc một số loại 'Row_Number()' precalculation để các giá trị có thể nằm trên các hàng riêng biệt. – ErikE