SQL:累积列&行总和

时间:2016-08-02 22:21:38

标签: sql sql-server sql-server-2008

我有一张桌子及其记录:

Profile | Level | CHgt | BHgt | SHgt | Z
ABCD1   | 1     | 15   | 11   | 50   | 0
ABCD1   | 2     | 15   | 11   | 70   | 0
ABCD1   | 3     | 15   | 11   | 70   | 0
ABCD2   | 1     | 15   | 11   | 60   | 0
ABCD2   | 2     | 15   | 11   | 80   | 0
ABCD2   | 3     | 15   | 11   | 80   | 0
ABCD3   | 1     | 15   | 11   | 40   | 0
ABCD3   | 2     | 15   | 11   | 60   | 0
ABCD3   | 3     | 15   | 11   | 60   | 0
ABCD1   | 1     | 15   | 11   | 50   | 0
ABCD1   | 2     | 15   | 11   | 70   | 0
ABCD1   | 3     | 15   | 11   | 70   | 0

我想计算Z,但我需要再创建两个变量(BHgt2,SHgt2:可以在计算的后端创建)

Profile | Level | CHgt | BHgt | SHgt | BHgt2 | SHgt2 | Z
ABCD1   | 1     | 15   | 11   | 50   | 11    | 0     | 26
ABCD1   | 2     | 15   | 11   | 70   | 22    | 120   | 157
ABCD1   | 3     | 15   | 11   | 70   | 33    | 190   | 238
ABCD2   | 1     | 15   | 11   | 60   | 11    | 0     | 26
ABCD2   | 2     | 15   | 11   | 80   | 22    | 140   | 177
ABCD2   | 3     | 15   | 11   | 80   | 33    | 220   | 268
ABCD3   | 1     | 15   | 11   | 40   | 11    | 0     | 26
ABCD3   | 2     | 15   | 11   | 60   | 22    | 100   | 137
ABCD3   | 3     | 15   | 11   | 60   | 33    | 170   | 218
ABCD1   | 1     | 15   | 11   | 50   | 11    | 0     | 26
ABCD1   | 2     | 15   | 11   | 70   | 22    | 120   | 157
ABCD1   | 3     | 15   | 11   | 70   | 33    | 190   | 238

基本上BHgt2是由Profile和Level& amp;累积的。 SHgt2是其值+前一个值的累积,但是,1级= 0,最后Z = CHgt + BHgt2 + SHgt2

我尝试过使用ROW_Number&与cte联合和组合;但我的思绪似乎陷入困境。

如果单个选择语句不可能,可能首先更新BHgt2和SHgt2的查询

然后选择Query以计算Z

任何人都有选择陈述的想法吗?这适用于SQL Server 2008

2 个答案:

答案 0 :(得分:1)

两个项目: 1)除了等级= 0之外,戈登的回应几乎是现场。应该是Level = 1

2)我不相信你想要的结果的最后一行是正确的,我认为你已经10岁了。如果我不对,请告诉我,我会重新访问这个。

Declare @Table table (Profile varchar(25),Level int,CHgt int,BHgt int, SHgt int, Z int)
Insert into @Table values
('ABCD1' , 1  , 15 , 11 , 50 , 0),
('ABCD1' , 2  , 15 , 11 , 70 , 0),
('ABCD1' , 3  , 15 , 11 , 70 , 0),
('ABCD2' , 1  , 15 , 11 , 60 , 0),
('ABCD2' , 2  , 15 , 11 , 80 , 0),
('ABCD2' , 3  , 15 , 11 , 80 , 0),
('ABCD3' , 1  , 15 , 11 , 40 , 0),
('ABCD3' , 2  , 15 , 11 , 60 , 0),
('ABCD3' , 3  , 15 , 11 , 60 , 0)

select A.Profile
      ,A.Level
      ,A.CHgt
      ,A.BHgt
      ,A.SHgt
      ,B.Bhgt2
      ,Shgt2 = case when Level = 1 then 0 else SHgt2 end
      ,Z     = CHgt + B.Bhgt2 + case when level = 1 then 0 else SHgt2 end 
From @Table A 
Cross Apply (Select Bhgt2 = sum(Bhgt)
                   ,SHgt2 = sum(SHgt)
              From  @Table B
              Where B.Profile = A.Profile and A.Level >= B.Level 
            ) B;

返回

Profile Level   CHgt    BHgt    SHgt    Bhgt2   Shgt2   Z
ABCD1   1       15      11      50      11      0       26
ABCD1   2       15      11      70      22      120     157
ABCD1   3       15      11      70      33      190     238
ABCD2   1       15      11      60      11      0       26
ABCD2   2       15      11      80      22      140     177
ABCD2   3       15      11      80      33      220     268
ABCD3   1       15      11      40      11      0       26
ABCD3   2       15      11      60      22      100     137
ABCD3   3       15      11      60      33      160     208

答案 1 :(得分:0)

在更新版本的SQL Server中,这会更容易。但您可以使用apply

执行此操作
select t.*, t2.Bhgt2,
       (case when level = 0 then 0 else SHgt2 end) as Shgt2,
       (CHgt + t2.Bhgt2 + (case when level = 0 then 0 else SHgt2 end) ) as Z
from t cross apply
     (select sum(Bhgt) as Bhgt2,
             sum(SHgt) as SHgt2
      from t t2
      where t2.profile = t.profile and t2.level <= t.level 
     ) t2;