2011-08-10 33 views
2

我有下表。每行存儲一系列指定列中的值。在SQL Server 2005中查找根據當前月份的列總數

create table MonthlyData (
Jan int not null, 
Feb int not null, 
Mar int not null, 
Apr int not null, 
May int not null, 
Jun int not null, 
Jul int not null, 
Aug int not null, 
Sep int not null, 
Oct int not null, 
Nov int not null, 
Dec int not null 
) 

insert into table (3, 1, 3, 4, 5, 6, 7, 8, 9, 4, 3, 2) 
. 
. 
. 

我想要做的是,根據年份的月份,對於每一行,總結了從第一列(月)截至及包括表示當前月列中的值(八月例如)。我懷疑這可能會涉及某些以月份爲參數的函數。當然會有成千上萬的行,而不是每行都是唯一的。

我不太清楚從哪裏開始,或者使用哪個sql內置函數/關鍵字來使用它。任何人都可以將我指向正確的方向嗎?

UPDATE:

基於舍甫琴科M的解決方案,我想出了這個。

declare @currentMonth int 
set @currentMonth = 8 
select sum(p1*Jan+p2*Feb+p3*Mar+p4*Apr+ 
    p5*May+p6*Jun+p7*Jul+p8*Aug+ 
    p9*Sep+p10*Oct+p11*Nov+p12*Dec) as 'Balance' 
from MonthlyData md 
cross join MatrixTable mt 
where mt.period = @currentMonth 

矩陣表具有是單位矩陣與左下半填充有1的而不是0的(列名開始與arbitry前綴,在這種情況下「P」,以及後跟一個數字)。在結尾添加一個額外的列以標識每一行。只要矩陣表足夠大,矩陣表對於其他問題以及將來也會有用。

+0

這張表的PK是什麼?你也打開改變架構? –

+0

是的,我願意改變模式。我可以包含一個自動遞增的PK。這不是一個問題。 – deutschZuid

回答

3

如果修改建議我在其他的答案是過於激進採納,那麼這裏到@Filip德沃思的解決方案替代:

SELECT 
    SUM(
    CASE v.number 
     WHEN 1 THEN Jan 
     WHEN 2 THEN Feb 
     WHEN 3 THEN Mar 
     WHEN 4 THEN Apr 
     WHEN 5 THEN May 
     WHEN 6 THEN Jun 
     WHEN 7 THEN Jul 
     WHEN 8 THEN Aug 
     WHEN 9 THEN Sep 
     WHEN 10 THEN Oct 
     WHEN 11 THEN Nov 
     WHEN 12 THEN Dec 
    END 
) AS Total 
FROM MonthlyData m 
    CROSS JOIN master..spt_values v 
WHERE v.type = 'P' 
    AND v.number BETWEEN 1 AND MONTH(GETDATE()) 

master..spt_values表系統表用於內部目的,但也可用於用戶查詢。其中一個子集包含一個從0到2047的整數列表,在許多情況下可以使用它作爲現成的tally table

+0

是的,不透明是做到這一點的方法。 – ErikE

+0

@Andriy M.你的回答非常好。這實際上啓發了我鬆散地創建了一個不同的解決方案。我創建了一個類似於單位矩陣的表格,除了矩陣的左下半部分都是1而不是0之外。我在這個矩陣表的末尾添加了一個名爲period的額外列,該列用作查找點並從1到n。然後,我將每個月的列與矩陣表中的相應列相乘。所以它有點像這樣(看我原來的帖子,因爲評論不允許我使用at標誌) – deutschZuid

2

您可以使用case語句來設置您不想歸零的數據。

declare @current_month int 
select @current_month = month(current_timestamp) 

select case when @current_month <= 1 then jan else 0 end 
    + case when @current_month <= 2 then feb else 0 end 
    + case when @current_month <= 3 then mar else 0 end 
    + case when @current_month <= 4 then apr else 0 end 
    + case when @current_month <= 5 then may else 0 end 
    + case when @current_month <= 6 then jun else 0 end 
    + case when @current_month <= 7 then jul else 0 end 
    + case when @current_month <= 8 then aug else 0 end 
    + case when @current_month <= 9 then sep else 0 end 
    + case when @current_month <= 10 then oct else 0 end 
    + case when @current_month <= 11 then nov else 0 end 
    + case when @current_month <= 12 then dec else 0 end 
from MonthlyData 
2

在我看來,您問題中的結構似乎更適合用於報表中的最終表格。作爲一個工作表,這將是有這樣的結構,更方便:

CREATE TABLE MonthlyData (
    Month int, 
    Value int 
) 

其中Month自然會保存值從1到12然後將數據求和將是非常容易的:

SELECT 
    SUM(Value) AS Total 
FROM MonthlyData 
WHERE Month BETWEEN 1 AND MONTH(GETDATE()) 
相關問題