2013-10-30 57 views
1

我真的需要接受CTE的結果,並計算出數據組的累積值。TSQL-2008 SUM(X)OVER(PARTITION ... ORDER BY CLAUSE)

數據集是:

PERIOD FT GROUP DEPT VALUE 
1 Actual KINDER MATH 200 
2 Actual KINDER MATH 363 
3 Actual KINDER MATH 366 
1 Budget KINDER MATH 457 
2 Budget KINDER MATH 60 
3 Budget KINDER MATH 158 
1 Actual HIGHSCH ENGLISH 456 
2 Actual HIGHSCH ENGLISH 745 
3 Actual HIGHSCH ENGLISH 125 
1 Budget HIGHSCH ENGLISH 364 
2 Budget HIGHSCH ENGLISH 158 
3 Budget HIGHSCH ENGLISH 200 
6 Budget HIGHSCH ENGLISH 502 
7 Budget HIGHSCH ENGLISH 650 
1 Actual COLL ENGLISH 700 
2 Actual COLL ENGLISH 540 
3 Actual COLL ENGLISH 160 
1 Budget COLL ENGLISH 820 
2 Budget COLL ENGLISH 630 
3 Budget COLL ENGLISH 800 

我要的是一個包含累積性量爲每FT,集團,系

所以基本上,我想它看起來像這樣的附加列:

PERIOD FT GROUP DEPT VALUE ACC VALUE 
1 Actual KINDER MATH 200 200 
2 Actual KINDER MATH 363 563 
3 Actual KINDER MATH 366 929 
1 Budget KINDER MATH 457 457 
2 Budget KINDER MATH 60 517 
3 Budget KINDER MATH 158 675 
1 Actual HIGHSCH ENGLISH 456 456 
2 Actual HIGHSCH ENGLISH 745 1201  
3 Actual HIGHSCH ENGLISH 125 1326  
1 Budget HIGHSCH ENGLISH 364 364 
2 Budget HIGHSCH ENGLISH 158 522 
3 Budget HIGHSCH ENGLISH 200 722 
1 Budget HIGHSCH ENGLISH 502 502 
2 Budget HIGHSCH ENGLISH 650 1152  
3 Budget HIGHSCH ENGLISH 336 1488  
1 Actual COLL ENGLISH 700 700 
2 Actual COLL ENGLISH 540 1240  
3 Actual COLL ENGLISH 160 1400  
1 Budget COLL ENGLISH 820 820 
2 Budget COLL ENGLISH 630 1450  
3 Budget COLL ENGLISH 800 2250  

如果我是在2012年SQL,我會使用類似這樣:

SELECT period 
    ,ft 
    ,group 
    ,dept 
    ,value 
    ,CASE 
     WHEN FT = 'Actual' THEN SUM(value) OVER (PARTITION BY dept, group, ft ORDER BY period) 
     ELSE value 
     END AS AccValue 
FROM myTable 

但是,我在2008年,不能使用這種方法,並難以對如何複製這些數據。

請任何人都可以幫忙嗎?

+1

爲什麼你不能在2008年複製這個?自2005年以來,「OVER」已經出現了。 – Kermit

+0

不僅僅是「over」... over.PARTITION BY和ORDER BY合計。我試了一下,每次都在訂單上出錯。在網上查看它說它不是2008年的一個功能。 –

+1

@FreshPrinceOfSO - 總計運行總計等的ORDER BY'是2012+ –

回答

1

這應該工作。 (我將禁止的列名從「GROUP」更改爲「GROUP_」)

with cte (PERIOD, FT, GROUP_, DEPT, VALUE, AccValue) as (select t1.PERIOD, t1.FT, t1.GROUP_, t1.DEPT, t1.VALUE, SUM(t2.VALUE) as AccValue 
          from   myTable t1 
          join myTable t2 on t1.PERIOD>= t2.PERIOD 
          and t1.FT = t2.FT 
          and t1.GROUP_ = t2.GROUP_   
          and t1.DEPT = t2.DEPT 
          group by t1.PERIOD, t1.FT, t1.GROUP_, t1.DEPT, t1.VALUE 
        ) 
           select PERIOD 
        ,FT 
        ,GROUP_ 
        ,DEPT 
        ,VALUE 
        ,CASE 
         WHEN FT = 'Actual' THEN AccValue 
         ELSE VALUE 
         END AS AccValue 
         from cte 
           order by GROUP_ desc, FT, PERIOD, DEPT desc, VALUE 
+0

謝謝。我試圖運行這個,到目前爲止我的數據集運行需要一分鐘,所以我覺得它不會是一個可行的解決方案。 :(更高效的低成本方法的任何想法? –

+0

如果您可以使用臨時表而不是CTE,並且在除VALUE之外的所有列上創建索引 – cadaver

+0

好吧,我明白如何創建臨時表並嘗試這樣做。我不知道如何做你建議的另一半。 –

1

簡單的INNER JOIN應該有效。除非我誤解了你,你想要的是一個正在運行的總數,對嗎?

本示例使用虛擬數據創建一個虛擬表,然後使用內部聯接作爲運行總數。從性能角度來看,公用表表達式可能更有效。但爲了簡單起見,內部加入我是優先的。

/* Dummy table */  

create table testing1 
(col1 int not null identity(1,1), 
col2 varchar(5), 
col3 int) 


insert into testing1 
values ('a', 10), ('a', 20), ('a', 30), ('b', 40), ('b', 50) 

/* Running total example */ 

SELECT a.col1 
      , a.col2 
      , a.col3 
      , SUM(b.col3) AS total 

FROM testing1 a INNER JOIN testing1 b 
    ON a.col1 >= b.col1 
    AND a.col2 = b.col2 

GROUP BY a.col1, a.col2, a.col3 
ORDER BY a.col1 



/* Edit to include Output */ 
col1 col2 col3 total 
1 a 10 10 
2 a 20 30 
3 a 30 60 
4 b 40 40 
5 b 50 90 
+0

甜...比我的評論更好;) –

+0

這沒有奏效。你是否可以使用http://sqlfiddle.com顯示你的輸出,以防萬一我錯了x –

+1

再試一次。如果您複製並粘貼,則需要刪除一個隨機的「'」。我刪除了它。另外,對於我的輸出中時髦的列格式感到抱歉,但您可以看到它執行了一次總計。 – rwking