SQL按特定顺序在表中创建累积和列

时间:2018-04-04 14:38:18

标签: sql grouping sql-server-2016

我为这个令人困惑的头衔道歉。我今天早上正在处理一个问题,我认为我在这里得到了所有人的帮助,但是我不能用master_line_num做我原本希望的事情。再一次,下面是我正在使用的数据的一小部分:

ID  Proj_Id    Year   Quarter  Value  **Cumu_Value**      Master_Line_Num
1   "C102"     2017      1    200.00    **200.00**           1
2   "C102"     2017      2    200.00    **400.00**           2
3   "C102"     2017      3    200.00    **600.00**           3
4   "C102"     2017      4    200.00    **800.00**           4
5   "C102"     2018      1    400.00    **1200.00**          5 
6   "C102"     2018      2    400.00    **1600.00**          6
7   "C102"     2018      3    400.00    **2000.00**          7
8   "C102"     2018      4    400.00    **2400.00**          8  
9   "B123"     2017      1    100.00    **100.00**           1
10  "B123"     2017      2    100.00    **200.00**           2
11  "B123"     2017      3    100.00    **300.00**           3
12  "B123"     2017      4    100.00    **400.00**           4            
13  "B123"     2018      1    200.00    **600.00**           5
14  "B123"     2018      2    200.00    **800.00**           6
15  "B123"     2018      3    200.00    **1000.00**          7
16  "B123"     2018      4    200.00    **1200.00**          8

我想要的值是“Cumu_Value”列。我试图通过按特定“Proj_Id”按季度将“值”列添加到季度来获取这些值。我最初尝试将“value”列乘以master_line_num列后得到,但后来意识到由于“value”列在年份之间变化而无效。

是否可以使用T-SQL计算此值,还是需要做一些更奢侈的事情?

3 个答案:

答案 0 :(得分:2)

SQL支持累积和作为窗口函数,因此很容易表达:

select . . . ,
      sum(value) over (partition by proj_id order by year, quarter) as cumulative_sum

答案 1 :(得分:2)

你需要一个Windowed Aggregate,这将返回累积总和:

sum(value) 
over (partition by proj_id 
      order by Year, Quarter
      rows unbounded preceding)

注意,如果没有(partition by proj_id order by Year, Quarter),请不要使用ROWS,因为它默认为RANGE,这可能会返回不同的结果,并且会产生更多的开销。 RANGE包含与当前值具有相同值的所有行。在你的情况下,它将返回:

 800
 800
 800
 800
2400
2400
2400
2400

编辑:

在检查了您的其他问题后,我发现您的数据中没有Master_Line_Num,因此您最好使用ORDER BY Year, Quarter

答案 2 :(得分:0)

您可以尝试这样的事情:

 select t1.id, t1.proj_ID, t1.Year, t1.Value, SUM(t2.Value) as Cumu_sum, Master_Line_Num
    from @tablename t1
    inner join @tablename t2 on t1.id >= t2.id
    group by t1.id, t1.Value
    order by t1.id