2013-06-12 35 views
19

我有一個數據SQL服務器連接表和數據透視

表兩張表1

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

表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  | 

我需要一個查詢將產生

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 

我是很新的旋轉和不知道支點是路要走此與否。

+1

有幾種類別?這是完整的清單嗎?未來會有更多嗎? – ErikE

+0

共有7大類。不要超越它。 –

回答

35

這應該工作:

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 
; 

或者交替:

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 
; 

這些具有相同的結果集和實際上可以處理查詢優化是相同的,但可能不是。當您開始在Sale表上添加條件時,最大的不同就是 - 您應該測試並查看哪個查詢效果更好。

但是,我可以建議你在表示層做旋轉嗎?例如,如果您正在使用SSRS,則使用矩陣控件非常容易,該控件將爲您完成所有的旋轉操作。這是最好的,因爲如果你添加一個新的Category,你將不會修改所有的SQL代碼!

有一種方法可以動態查找要轉移的列名,但它涉及動態SQL。儘管這是可能的,但我並不真的推薦這是最好的方法。

另一種方式可以工作將預處理此查詢 - 這意味着設置在Category表重寫一個VIEW包含所有存在的現存類別的觸發器。這確實解決了我提到的很多其他問題,但再次,使用表示層是最好的。

注意:如果您的列名稱(以前的值)是數字或以數字開頭,則必須在方括號中引用它們,如PIVOT (Max(Value) FOR CategoryId IN ([1], [2], [3], [4])) P。或者,您可以在查詢的PIVOT部分之前修改這些值以預先添加一些字母,以便列列表不需要轉義。欲瞭解更多信息,請查看SQL Server中標識符的規則。

+0

由於真正的幫助....首先查詢工作,在福斯特查詢請加「我」之後INNER JOIN dbo.SaleItem OR INNER JOIN dbo.SaleItem我 感謝 –

+0

請務必檢查是否'MAX()'是適當 - 如果每個SaleID +類別可能有多個,則可能需要'Sum()'或某種'Row_Number()'預先計算,以便這些值可以位於不同的行上。 – ErikE