2016-10-28 13 views
1

は、私はこのようなサンプルを持つテーブルを持っています。この例ではSQL Serverの行のデータを合計する方法は?

enter image description here

が1日目、2日目、3日目とはし​​ているが、実際のデータではDay100て1日目である可能性があります。

TSTID = 1の場合、Day1からDay3、Day2からDay10など特定の範囲の行のデータを合計するにはどうすればよいですか?

+0

は、テキスト形式の代わりに、画像 –

答えて

1

このアプローチは、実際には動的ではなく、もう少し動的です。フィールドリストを指定したり動的に作成したりする必要はありません。

Declare @YourTable table (TSTID int,Year int,Day1 int,Day2 int,Day3 int) 
Insert Into @YourTable values 
(1,2015,1000,4000,7000), 
(2,2015,2000,5000,8000), 
(3,2015,3000,6000,9000) 

Declare @DayR1 int = 1 
Declare @DayR2 int = 3 

Select A.TSTID 
     ,TotalSum = sum(B.Value) 
From @YourTable A 
Cross Apply (Select Value=cast(value as int) 
       From [dbo].[udf-EAV]((Select A.* for XML RAW)) 
       Where Attribute Like 'Day%' 
       and cast(Replace(Attribute,'Day','') as int) between 1 and 3 
      ) B 
Where A.TSTID = 1 
Group By A.TSTID 

戻り

TSTID TotalSum 
1  12000 

は今、私はここにヘルパー関数を使用して行います。事実上すべてのデータセットをEAV構造(エンティティ属性値)に変換するTVFです。 LARGERデータセットでは、CLEARLY UNPIVOTのパフォーマンスが向上します。私は

CREATE FUNCTION [dbo].[udf-EAV](@XML xml) 
Returns Table 
As 
Return (
    with cteKey(k) as (Select Top 1 xAtt.value('local-name(.)','varchar(100)') From @XML.nodes('/row') As A(xRow) Cross Apply A.xRow.nodes('./@*') As B(xAtt))  

    Select Entity = xRow.value('@*[1]','varchar(50)') 
      ,Attribute = xAtt.value('local-name(.)','varchar(100)') 
      ,Value  = xAtt.value('.','varchar(max)') 
    From @XML.nodes('/row') As A(xRow) 
    Cross Apply A.xRow.nodes('./@*') As B(xAtt) 
    Where xAtt.value('local-name(.)','varchar(100)') Not In (Select k From cteKey) 
) 
-- Notes: First Field in Query will be the Entity 
-- Select * From [dbo].[udf-EAV]((Select UTCDate=GetUTCDate(),* From sys.dm_os_sys_info for XML RAW)) 
+0

のサンプルデータを追加し、APPLYあなたが機能をしたくない場合は、ロジックは簡単CROSSに移植することができることを、追加する必要があります

はあなたのためにどうもありがとうございますあなたが提供したソリューションは素晴らしい作品です。 – John

+0

@John幸せに助けて –

関連する問題