【问题标题】:sql reset updating rows when a value changes当值更改时,sql重置更新行
【发布时间】:2015-11-17 18:58:28
【问题描述】:

我有一张如下表:

  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

如何按照我的说明更新表格,以便在“代码”列中的值更改时重置添加值?请帮忙,我需要以下结果,谢谢!

  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

【问题讨论】:

  • 为什么要同时使用 MySQL 和 MS SQL Server 标签?您使用的是哪个 dbms? (不要标记未涉及的产品...)
  • 对不起@jarlh 这是 sql server。我刚刚删除了 mysql 标签。

标签: sql sql-server tsql


【解决方案1】:

更新条款影响整个集合。所以你不能定义它应该在更改代码后重置@sum

尝试使用窗口函数 Sum(value) Partition by code 和 Order By ID

例如

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

你可以用这个集合来更新你的表。

【讨论】:

  • 非常感谢@CPmunich 提供快速简单的解决方案。
【解决方案2】:

您可以使用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

【讨论】:

  • 谢谢@lad2025,您的解决方案也很有帮助!
猜你喜欢
  • 2010-10-17
  • 1970-01-01
  • 1970-01-01
  • 2013-11-30
  • 2014-08-30
  • 1970-01-01
  • 1970-01-01
  • 2022-07-22
  • 2014-10-14
相关资源
最近更新 更多