2014-09-10 71 views
0

SQL Afficianados,SQL來計算「最新」的值在每月列

有一定是比我要在路上一個更好的辦法...

SQL Fiddle HERE

使用SQL Server 2008.簡而言之,我有一個以月爲列的表格。即:

CREATE TABLE MyData (MyID VARCHAR(10), 
    JAN MONEY, FEB MONEY, MAR MONEY, APR MONEY, MAY MONEY, JUN MONEY, 
    JUL MONEY, AUG MONEY, SEP MONEY, OCT MONEY, NOV MONEY, DEC MONEY); 

鑑於N的月份值(如整數,其中1 = JAN和12 = DEC),我要計算從第一個月「最新」值至第N個月。

所以,對於這個簡單的數據:

INSERT INTO MyData (MyID, JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC) 
SELECT 'Rec1', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 
UNION ALL SELECT 'Rec2', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 
UNION ALL SELECT 'Rec3', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 
; 

我想在任何一個月值傳遞,並添加了正確的月份列。鑑於上面的樣本數據,這裏是基於傳遞在一個月的價值預期結果的圖表......

Month Value | Expected Result | 
------------+------------------ 
1   | 3 
2   | 9 
3   | 18 
4   | 30 
5   | 45 
6   | 63 
7   | 84 
8   | 108 
9   | 135 
10   | 165 
11   | 198 
12   | 234 

我知道我可以用一個CASE語句這樣做:

DECLARE @v_Month INT = 2 

SELECT CASE 
    WHEN @v_Month = 1 THEN SUM(JAN) 
    WHEN @v_Month = 2 THEN SUM(JAN) + SUM(FEB) 
    WHEN @v_Month = 2 THEN SUM(JAN) + SUM(FEB) + SUM(MAR) 
    --You get the idea. The pattern would continue for the rest of the months. 
    ELSE 0 
END AS ToDateSum 
FROM MyData 

但是有沒有更好的方法?教我,哦,很棒的SQL Server。

回答

1

您可以使用unpivot將數據更改爲更適合的形狀。首先以這種方式存儲它可能更有意義。

declare @v_Month int = 2; 

with u as (
    select 
    myid, [month], amount 
    from (
    select 
     myid, jan [1], feb [2], mar [3], apr [4], may [5], jun [6], 
     jul [7], aug [8], sep [9], oct [10], nov [11], dec [12] 
    from 
     MyData 
) p 
    unpivot (
    amount for [month] in ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12]) 
) u 
) select 
    sum(amount) 
from 
    u 
where 
    [month] <= @v_Month; 

Example SQLFiddle

可以簡化這個有點,如果你想保持數據的相同結構:

select 
    sum(amount) 
from (
    select 
    myid, jan [1], feb [2], mar [3], apr [4], may [5], jun [6], 
    jul [7], aug [8], sep [9], oct [10], nov [11], dec [12] 
    from 
    MyData 
) p 
unpivot (
    amount for [month] in ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12]) 
) u 
where 
    [month] <= @v_Month; 
+0

我真的很感激你爲了代表我寫代碼而付出的努力。 PIVOT和UNPIVOT結構在SQL Server中是新的(通過這篇文章),我將努力在將來適當地使用這些概念。 – laughsloudly 2014-09-12 17:12:56

0

像這樣將工作:

declare @MyDesiredMonth int = 3 

with normalized_view as 
(
      select MyId , Month = 1 , Value = Jan from MyData 
    UNION ALL select MyId , Month = 2 , Value = Feb from MyData 
    UNION ALL ... 
    UNION ALL select MyId , Month = 11 , Value = Nov from MyData 
    UNION ALL select MyId , Month = 12 , Value = Dec from MyData 
) 
select MonthlyTotal = sum(Value) 
from normalized_view t 
where t.Month = @myDesiredMonth 

或者,像這樣的東西:

declare @MyDesiredMonth int = 3 

select MonthlyTotal = sum(case @MyDesiredMonth 
          when 1 then t.Jan 
          when 2 then t.Feb 
          ... 
          when 11 then t.Nov 
          when 12 then t.Dec 
          end 
         ) 
from MyTable t 

任何一個人都應該與執行計劃一起工作,可能會結束類似的工作。