2017-10-11 32 views
1

我想我正在嘗試做一些無法完成的事情。我正在嘗試創建一個數據透視表,同時通過聚合兩個不同的列來完成兩個支點。我創建了一個非常簡單的示例,以使這一點更易於理解。創建數據透視表與聚合無需加入

CREATE TABLE two_aggregate_pivot (
    ID INT, 
    category CHAR(1), 
    value INT 
) 

INSERT INTO dbo.two_aggregate_pivot 
    (ID, category, value) 
VALUES (1, 'A', 100), 
     (1, 'B', 97), 
     (1, 'D', NULL), 
     (2, 'A', 86), 
     (2, 'C', 83), 
     (2, 'D', 81)    

我可以透視得到類別的數量如下:

SELECT piv1.ID, 
     [A] AS cat_A, 
     [B] AS cat_B, 
     [C] AS cat_C, 
     [D] AS cat_D 
FROM 
(SELECT ID, category FROM dbo.two_aggregate_pivot) SRC 
PIVOT 
(
    COUNT(category) 
    FOR category IN ([A],[B],[C],[D]) 
) piv1 

而且我得到了我想要的東西。

ID cat_A cat_B cat_C cat_D 
1 1  1  0  1 
2 1  0  1  1 

也是如此,我可以寫一個完全獨立的查詢,從MAX(值)添加源選擇值列,而不是總量,並獲得最大價值的支點。

ID val_A val_B val_C val_D 
1 100  97  NULL NULL 
2 86  NULL 83  81 

但我無法弄清楚是如何讓他們兩個。

ID cat_A cat_B cat_C cat_D val_A val_B val_C val_D 
1 1  1  0  1  100  97  NULL NULL 
2 1  0  1  1  86  NULL 83  81 

我一直在使用CASE語句來檢查IS NOT NULL在這裏看到的例子在計算器,但是,這並不爲我工作,我不認爲,因爲我可以有一個真的既缺失值和現存值空值。我可以創建兩個CTE,一個與每個PIVOT,然後加入它們。這給了我想要的表格,但是它強制對錶格進行聚集索引掃描兩次,然後再加上連接運算符。這個表格非常大,而且性能很重要,所以我想嘗試找到一種方法來在同一個聚集索引掃描中執行兩個樞軸。

這可能嗎?

回答

1

也許是交叉應用來解除您的數據。我應該補充一點,動態變化是一件小事。

Select * 
From (
      Select ID 
        ,B.* 
      From two_aggregate_pivot A 
      Cross Apply (values ('cat_'+category ,1) 
           ,('val_'+category ,value) 
         ) B (Item,Value) 
     ) src 
    Pivot (sum(value) for item in ([cat_A],[cat_B],[cat_C],[cat_D],[val_A],[val_B],[val_C],[val_D])) pvt 

返回

ID cat_A cat_B cat_C cat_D val_A val_B val_C val_D 
1 1  1  NULL 1  100  97  NULL NULL 
2 1  NULL 1  1  86  NULL 83  81 
+0

對不起,長延遲響應於此。我一直在試圖弄清楚這個魔法是如何工作的。查看內部查詢有幫助。我想我可以修改這個以適應我的情況,並且我將編輯這個評論以表明它如何執行相對於加入這兩個樞紐。 –

+0

@RobertSievers對遲到的反應抱歉。我被拉走了。讓我知道如果我可以幫助 –

+0

那麼,這裏是結果。這兩種PIVIOT JOIN方法的效率比按照執行子樹成本衡量的CROSS APPLY低30%。果然,CROSS APPLY只有一半的邏輯讀取次數,但它需要兩倍的CPU時間。實際持續時間幾乎完全相同。所以,如果你有一個快速的磁盤,使用兩個樞軸聯接方法。如果您的磁盤速度較慢且CPU速度較快,請使用CROSS APPLY。 –