2011-08-10 7 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) 
. 
. 
. 

私は何をしたい(最初のカラム(月)現在の月を表す列までを含むからの値を合計し、行ごとに、年の月に応じて、8月です例えば)。私はおそらくこれがパラメータとして月を取る何らかの種類の関数を含むと思われる。もちろん、何千もの行があり、すべての行が一意ではありません。

これをどこから始めるべきか、またはこれに使用する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 

マトリックス表にしている代わりに0の1者で満たされた左下半分(列名が「P」、この場合、arbitryプレフィックスで始まり、そして数が続く)を有する恒等行列です。最後に追加の列が追加され、各行が識別されます。行列テーブルは、十分に大きなものであれば、今後も他の問題にも役立ちます。

+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表です内部目的のために使用されるシステム・テーブルですが、ユーザーの問合せでも使用できます。そのサブセットの1つには、0から2047までの整数のリストが含まれており、多くの場合、既製のtally tableとして使用できます。

+0

はい、アンピボットはそれを行う方法です。 – ErikE

+0

@Andriy M.あなたの答えはとても良いです。実際には、このアイデアに基づいていろいろなソリューションを作り出すことができました。行列の左下半分が0の代わりにすべて1であることを除いて、恒等行列に似た表を作成しました。この行列テーブルの終わりにperiodと呼ばれる余分な列を追加しました。これはルックアップのポイントとして機能し、1からnになります。私はその後、毎月の列に行列テーブルの対応する列を掛けます。だから、ちょっとこのようになります(私の元の投稿を見て、私がアットマークを使用することを許可していない) – 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()) 
関連する問題