当值更改时,sql重置更新行

时间:2015-11-17 10:19:09

标签: sql sql-server tsql

我有一张表格如下:

  id    code   value  total
==========================
1     A/01    5       
2     A/01    8       
3     A/01    6       
1     A/02    8       
2     A/02    3       
3     A/02    7       
1     A/03    6       
2     A/03    9       
3     A/03    2       

我想用相同行+前一行的值更新总数。我声明了如下变量并更新表:

DECLARE @sum int
SET @sum = 0
UPDATE @table set total = @sum, @sum = @sum + value

如果我选择第一个代码,那就完美了:

SELECT * FROM table WHERE code='A/01'

id    code   value  total
==========================
1     A/01    5       5
2     A/01    8       13
3     A/01    6       19

但是如果我选择整个表格,那么就这样做:

  id    code   value  total
==========================
1     A/01    5       5
2     A/01    8       13
3     A/01    6       19
1     A/02    8       27
2     A/02    3       30
3     A/02    7       37
1     A/03    6       43
2     A/03    9       52
3     A/03    2       54

如何按照我的解释更新表格,以便在“code”列中的值发生变化时重置添加值?请帮忙,我需要以下结果,谢谢!

  id    code   value  total
==========================
1     A/01    5       5
2     A/01    8       13
3     A/01    6       19
1     A/02    8       8
2     A/02    3       11
3     A/02    7       18
1     A/03    6       6
2     A/03    9       15
3     A/03    2       17

2 个答案:

答案 0 :(得分:1)

您可以使用windowed SUM来计算总数:

WITH cte AS
(
  SELECT a.id ,   a.code , a.[value] , 
  total = SUM(a.[value]) OVER (PARTITION BY code ORDER BY id)
  FROM #mytable a
)
UPDATE m
SET total = c.total
FROM #mytable m
JOIN cte c
  ON m.id = c.id 
 AND m.code = c.code;

SELECT *
FROM #mytable
ORDER BY code, id;

LiveDemo

您无法在UPDATE中直接使用窗口函数,如:

UPDATE #mytable
SET total = SUM([value]) OVER (PARTITION BY code ORDER BY id)

因此您需要先使用subquery/cte来计算总和。

修改

您的第一次尝试:

DECLARE @sum int = 0;
UPDATE @table set total = @sum, @sum = @sum + value;

可能是危险的,并返回不可预测的结果。 (忘掉关于多个代码的片刻并假设表中只有'A/01'。您已经假设sum将逐行增加id

但如果涉及并行性,那么会有什么问题?

如果您需要此类操作,请阅读有关 quirky update

的更多信息

答案 1 :(得分:1)

Update-Clause影响整个集合。因此,您无法定义在更改代码后应重置@sum

尝试使用窗口函数Sum(value)按代码分区和按ID排序

例如

SELECT id, value
       Sum(value) OVER (PARTITION BY code ORDER BY id
                            ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS total     
FROM [table]

这套你可以用来更新你的桌子。