更新行组以从行总和中删除特定的总计SQL

时间:2018-06-30 05:04:26

标签: sql sql-server sql-update sql-server-2014

在示例中,我想从Subtracted分组的表2中TABLE 1的总和中减去ValueBefore中的GroupID值。从第一行减去余数,然后从组中的下一行减去该值(依此类推),直到减去总数。

有没有一种方法可以做到这一点而无需遍历行来获取其余部分?

我的表1:

TABLE 1 of subtracting value
GroupID    Subtracted
  1          32
  2          30

我的表2:

ID   GroupID     ValueBefore     Reduction      ValueAfter   
 1     1             10            -10             0
 2     1             15            -15             0 
 3     1              5             -5             0 
 4     1              5             -2             3
 5     2             40            -30            10
 6     2             30              0            30

2 个答案:

答案 0 :(得分:0)

一种方法是使用ValueBefore来计算SELECT t2.ID, t2.GroupID, t2.ValueBefore, r.ValueBefore AS rValueBefore FROM Table2 AS t2 LEFT JOIN Table2 AS r ON t2.GroupID = r.GroupID AND t2.ID >= r.ID ORDER BY t2.ID, r.ID 的总投放量。

此查询:

ID  GroupID ValueBefore rValueBefore
------------------------------------
1   1       10          10
2   1       15          10
2   1       15          15
3   1       5           10
3   1       5           15
3   1       5           5
4   1       5           10
4   1       5           15
4   1       5           5
4   1       5           5
5   2       40          40
6   2       30          40
6   2       30          30

产生以下输出:

ID

如果您在SUM上按rValueBeforeSELECT t2.ID, t2.GroupID, t2.ValueBefore, SUM(r.ValueBefore) AS Total FROM Table2 AS t2 LEFT JOIN Table2 AS r ON t2.GroupID = r.GroupID AND t2.ID >= r.ID GROUP BY t2.ID, t2.GroupID, t2.ValueBefore 分组,则可以计算运行总计:

ID  GroupID ValueBefore Total
-----------------------------
1   1       10          10
2   1       15          25
3   1       5           30
4   1       5           35
5   2       40          40
6   2       30          70    

输出:

ValueAfter

您现在可以使用以下方法计算SELECT t.ID, t.GroupID, t.ValueBefore, Total, Subtracted, CASE WHEN Total - t1.Subtracted < 0 THEN 0 ELSE Total - t1.Subtracted END AS ValueAfter FROM ( SELECT t2.ID, t2.GroupID, t2.ValueBefore, SUM(r.ValueBefore) AS Total FROM Table2 AS t2 LEFT JOIN Table2 AS r ON t2.GroupID = r.GroupID AND t2.ID >= r.ID GROUP BY t2.ID, t2.GroupID, t2.ValueBefore ) as t JOIN Table1 AS t1 ON t.GroupID = t1.GroupID ORDER BY ID

ID  GroupID ValueBefore Total   Subtracted  ValueAfter
------------------------------------------------------- 
1   1       10          10      32          0
2   1       15          25      32          0
3   1       5           30      32          0
4   1       5           35      32          3
5   2       40          40      30          10
6   2       30          70      30          40

输出:

nil

Demo here

答案 1 :(得分:0)

我将使用累加和和一些相对简单的比较:

select t2.*,
       (case when t2.running_value - t2.valuebefore < t1.subtracted
             then 0
             when t2.running_value < t1.subtracted
             then t2.running_value - t1.subtracted
             else t2.valuebefore
        end) as reduction,
       (case when t2.running_value < t1.subtracted then 0
             else t2.running_value - t1.subtracted
        end) as ValueAfter
from (select t2.*,
             sum(valuebefore) over (partition by groupid order by id) as running_value
      from t2
     ) t2 join
     t1
     on t2.groupid = t1.groupid;